0

I'm having trouble centering my container's item.

Screenshot of the site

I need to align the third item to the center using display: grid.

I've already tried to use flexbox, but it looks worse for a responsive website.

.projetos {
  flex-direction: column;
  padding: 3rem 3%;
  text-align: center;
  justify-content: center;
}

.projetos-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
  text-align: center;
}

.projetos-box img {
  width: 100%;
  max-width: 40rem;
  border-radius: 1rem;
}
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>
tacoshy
  • 10,642
  • 5
  • 17
  • 34
zAllan
  • 1
  • 1
    Basically you want a grid item not to respect the grid layout. This doesn't really make sense to me. For the layout you are looking for you should use display flex. – JSON Derulo Jun 03 '23 at 13:47
  • So how to make this responsive using display flex? – zAllan Jun 03 '23 at 13:50
  • There is a fun way to learn display flex: https://flexboxfroggy.com/ Afterwards you should be able to implement your design with ease. – JSON Derulo Jun 03 '23 at 13:53

2 Answers2

1
  1. Convert the Container to flexbox by using display: flex;
  2. Use flex-wrap: wrap to allow a break to a new row
  3. Calculate the width of an element to create a 2 column layout to respect the gap
  4. Center the items by using justify-content: center on the flex-container

:root {
  --gap: 2rem;
}

.projetos {
  flex-direction: column;
  padding: 3rem 3%;
  text-align: center;
  justify-content: center;
}

.projetos-container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap) ; 
  justify-content: center;
}

.projetos-box {
  width: calc((100% - var(--gap)) / 2);
}

.projetos-box img {
  width: 100%;
  max-width: 40rem;
  border-radius: 1rem;
}
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>
JSON Derulo
  • 9,780
  • 7
  • 39
  • 56
tacoshy
  • 10,642
  • 5
  • 17
  • 34
  • out of curious :) so this solution is display:flex, instead of grid, is that mean there is no solution for display:grid? – SKLTFZ Jun 03 '23 at 14:11
  • 1
    Well, you could solve it if you know that there is **always** an uneven amount of grid items but which is hardly responsive. You could also do it with JS. But as a senior, I would state that you should use the right tool instead of trying to find hacks just to sue the worse tool for a case (with even worse compatibility). Especially with responsiveness in mind, it will be trickier the further you go. If you want a 3-column layout it becomes more trouble for the grid if you have 4 or 5 elements while flexbox won't care much about it. – tacoshy Jun 03 '23 at 14:14
1

You may trick it and use transform but need to check a few things .

  • Is this standing alone on a row ? (an odd position)
  • Is this the last one ?
  • if both yes, move 50% aside of its own width + (for 2col) half of the gap set.

But it is basicly a flex job i would say :)

here is below a few test to demonstrate the idea and not mind about how many children you have in your grid.

.projetos {
  flex-direction: column;
  padding: 3rem 3%;
  text-align: center;
  justify-content: center;
  /* show me center */
  background:linear-gradient(to left,ivory 50%, silver 50%);
}

.projetos-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
  text-align: center;
}

.projetos-box img {
  width: 100%;
  max-width: 40rem;
  border-radius: 1rem;
}

/* trick me */
.projetos-box:nth-child(odd):last-child {
  transform: translatex(calc(50% + 1rem));
}
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>
<section class="projetos" id="projetos">
  <h2>Projetos <span>Recentes</span></h2>

  <div class="projetos-container">
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>

    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
    <div class="projetos-box">
      <img src="https://via.placeholder.com/200.jpg" alt="" width="500">
    </div>
  </div>
</section>

If you dislike the transform trick, span this last odd element through both columns and give an auto margin.

G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • A good hack for a 2-column grid. But yes as yous aid it basically is a flexbox job. It will get harder there more columns you have and having just 2 columns always is not very responsive imho. – tacoshy Jun 03 '23 at 14:22
  • @tacoshy , yep , indeed, and if you go with auto-fill or mediaquerie, then it is all lost into a nightmare ;) it is definitely a flex job for me. – G-Cyrillus Jun 03 '23 at 14:23
  • n-th child is the key, but then have to hardcode the item's size :) – SKLTFZ Jun 03 '23 at 14:37
  • @SKLTFZ if you use grid-row:1/-1; + margin-inline:auto; You do not have too mind its width. For the translate way; just give a width: 100%(if not already applied by defaut or same as other elements) so it fills the whole cell and then it shifts aside by its own half – G-Cyrillus Jun 03 '23 at 14:52