Steve
Steve

Reputation: 14912

CSS grid as child of flexbox not behaving as expected

I have often created a responsive 3-column grid with CSS display: grid. My HTML markup inside the grid has 3 div items, so the grid creates 3 columns

display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));

enter image description here

and as you resize the window it collapses to 1 column, as expected:

https://codepen.io/smlombardi/pen/oqMjrd?editors=1100

.hero-modules {
  display: grid;
  grid-gap: 2rem;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.hero-modules .hero-item {
  border: 1px solid #000;
  text-align: center;
}

.hero-modules .hero-item h3 {
  font-size: 22px;
  text-align: center;
}
<div class="hero-modules">
  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>

  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>

  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>
</div>

Now I need to use this grid inside a Flexbox, to center the enclosing box to float on the link background:

enter image description here

And as you can see, the grid collapses (the dotted border is only added to show the extents of the flex child).

https://codepen.io/smlombardi/pen/PRBPWB?editors=1100

.hero {
  background-color: pink;
  display: flex;
  min-height: 600px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 1px solid #000;
}

.box {
  border: 1px dotted #000;
  text-align: center;
}

.button-unit {
  text-align: center;
  margin-top: 20px;
}

.hero-modules {
  display: grid;
  grid-gap: 2rem;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.hero-modules .hero-item {
  border: 1px solid #000;
  text-align: center;
}

.hero-modules .hero-item h3 {
  font-size: 22px;
  text-align: center;
}
<div class="hero">
  <div class="box">
    <div>
      <h1 class="hero-heading">Check out these new features</h1>
    </div>

    <div class="hero-modules">
      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>

      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>

      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>
    </div>

    <div class="button-unit">
      <button class="btn btn-secondary mb-3">Got It</button>
      <p>
        <a class="remind-me-later" href="">Remind me later</a>
      </p>
    </div>
  </div>
</div>

<div class="container">
  <div class="row">
    <div class="col">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nostrum molestias earum beatae, minima provident sunt a et? Voluptatibus sequi ipsum ad asperiores soluta odio, nam nobis quas non totam ut officiis itaque eveniet, maiores saepe id cum consequuntur.
      Molestias suscipit quia laudantium laborum nemo ab officia, nihil esse mollitia sunt!
    </div>
  </div>
</div>

Why is this happening? Is there something I am missing not allowing the grid to behave normally?

Upvotes: 19

Views: 1538

Answers (3)

Joginaidu Gopisetti
Joginaidu Gopisetti

Reputation: 13

You can do it using display: flex property. Below is the code for it.

.hero-modules {
  display: flex;
}

.hero-modules .hero-item {
  flex: 1;
  margin: 10px;
  border: 1px solid #000;
  text-align: center;
}

.hero-modules .hero-item h3 {
  font-size: 22px;
  text-align: center;
}
<div class="hero-modules">
  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>

  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>

  <div class="hero-item">
    <div>
      <h3>Title of Item</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
    </div>
    <div>
      <a class="hero-read-more">Read more</a>
    </div>
  </div>
</div>

Upvotes: 0

Shamim
Shamim

Reputation: 31

Add **display:flex** property to your main container.

 .Main {
     display:flex;
  }
 div {
   flex: 1;
 }

Then All div will be act as grid for more information refer below link. https://www.w3schools.com/css/css3_flexbox.asp

Upvotes: 1

Patrick Dark
Patrick Dark

Reputation: 2259

The Simple Answer:

The grid container's automatic width is essentially whatever it would be if it weren't a grid container.

In the first example, the grid container width is only constrained by the width of the document and any default margins.

In the second example, the grid container width is the width of an ancestor flex item with default shrinkwrap behavior that's dependent on the width of its content, the text "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae." (To put it more directly, the width of the grid container is the width of the preceding, quoted sentence.)

The Extended Answer:

The grid container (.hero-modules) has width: auto (the default). Per https://drafts.csswg.org/css-grid/#grid-container:

As a block-level box in a block formatting context, it is sized like a block box that establishes a formatting context, with an auto inline size calculated as for non-replaced block boxes.

The term "auto inline size" is just another way of saying width: auto in this case. (The "auto inline size" is height: auto in vertical text.)

"A block box that establishes a formatting context" is the same as a box with display: flow-root. Changing display: grid to display: flow-root will demonstrate what width is being used to calculate the width of the grid container as a result of width: auto.

So now we know where the grid container size comes from.

The flex item's size comes from flex-grow: 0 and flex-shrink: 1 (the defaults), which makes its width shrink and not grow. The basis for the flex item's width is flex-basis: auto (the default), which resolves to flex-basis: content. The content is the text "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae."

So now we know why the flex item doesn't expand and what its width is based on.

Fixing This Layout:

This flex layout should not be column-based; it should be row-based. Columns are inside the sole flex item, but not flex items themselves and dimensional flexibility is desired on the x-axis, not the y-axis.

So, flex-direction: column needs to become flex-direction: row.

The flex layout needs to grow (on the x-axis) to fit available space, so flex-grow: 1 needs to be specified on the flex item (.box).

Lastly, the grid-template-columns value should use auto-fit, not auto-fill if horizontal centering is desired. Grid items can be centered with justify-content: center applied to the grid container element.

(With auto-fill, invisible placeholder grid items will be placed to fill out the layout, which will cause the three present grid items to be aligned to the left with a bunch of invisible placeholder items filling out the remaining blank space to their right. With auto-fit, those placeholder grid items are simply discarded and that space is freed for horizontal alignment.)

.hero {
  background-color: pink;
  display: flex;
  min-height: 600px;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  border: 1px solid #000;
}

.box {
  border: 1px dotted #000;
  flex-grow: 1;
  text-align: center;
}

.button-unit {
  text-align: center;
  margin-top: 20px;
}

.hero-modules {
  display: grid;
  grid-gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  justify-content: center;
}

.hero-modules .hero-item {
  border: 1px solid #000;
  text-align: center;
}

.hero-modules .hero-item h3 {
  font-size: 22px;
  text-align: center;
}
<div class="hero">
  <div class="box">
    <div>
      <h1 class="hero-heading">Check out these new features</h1>
    </div>

    <div class="hero-modules">
      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>

      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>

      <div class="hero-item">
        <div>
          <h3>Title of Item</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta est ipsa recusandae.</p>
        </div>
        <div>
          <a class="hero-read-more">Read more</a>
        </div>
      </div>
    </div>

    <div class="button-unit">
      <button class="btn btn-secondary mb-3">Got It</button>
      <p>
        <a class="remind-me-later" href="">Remind me later</a>
      </p>
    </div>
  </div>
</div>

<div class="container">
  <div class="row">
    <div class="col">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nostrum molestias earum beatae, minima provident sunt a et? Voluptatibus sequi ipsum ad asperiores soluta odio, nam nobis quas non totam ut officiis itaque eveniet, maiores saepe id cum consequuntur.
      Molestias suscipit quia laudantium laborum nemo ab officia, nihil esse mollitia sunt!
    </div>
  </div>
</div>

Upvotes: 5

Related Questions