3

I am trying to vertically align divs with flexbox, by using the align-content: center. It works fine in Firefox and IE, but it does not vertically align in Chrome. In Chrome the divs stays on top.

<div class="products-wrapper">
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
</div>

And CSS:

.products-wrapper {
    width: 100%;
    min-height: 100vh;
    /* FLEX */
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-content: center;
}

.product {
    max-width: 250px;
    padding: 10px;
}

.product img {
    display: block;
    margin: 0 auto;
    max-height: 250px;
    max-width: 250px;
}

I have also been trying align-items: center; which centers the divs vertically, but it will not be a straight line with the images and text if I have different amount of text for example.

Anyone with a solution how to vertically center divs (straight), which works in all browsers?

Image example:

Image example

Edit: If you don't need the height to be dynamic, align-items: center; will work with (for example) max-height: 400px; on the .product div. Not really what I wanted though.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Nifel
  • 167
  • 1
  • 3
  • 12
  • I see the problem is not that the `product` elements don't _align_ in the same way, but they get a 100% height in Chrome. Not yet sure why. – Mr Lister Apr 22 '18 at 17:58
  • It seems that if you will set height to .product you will solve it? – A. Meshu Apr 22 '18 at 18:15
  • @A.Meshu If you know what the height of the products needs to be, sure. – Mr Lister Apr 22 '18 at 18:18
  • @A.Meshu Yes, it works if the height is set in stone. But there must be a better solution which works dynamically. – Nifel Apr 22 '18 at 18:21
  • Since the amount of text dinamically change, i can't think of something else but setting it (and handle overflow etc). – A. Meshu Apr 22 '18 at 18:29
  • This post may help you understand the problem and provide a solution: [*How does `flex-wrap` work with `align-self`, `align-items` and `align-content`?*](https://stackoverflow.com/q/42613359/3597276) – Michael Benjamin Apr 23 '18 at 18:27

2 Answers2

6

In order to achieve what you want you'll need to use align-items: flex-start, this way all items will be aligned to the top of their line. And to center vertically you're looking for the align-items: center property which aligns the items in the flex container along the cross axis, which in your case you'll have to use in an outer wrapper to make sure the products div is centered in the page.

The align-content: center property comes into play only when there is more than one line (wrapped content).

A better explanation about the difference between those two properties is in the answer to this stackoverflow question

.outer-wrapper {
  width: 100%;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.products-wrapper {
    width: 100%;
    /* FLEX */
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    background-color: gray;
    align-items: flex-start;
}

.product {
    max-width: 250px;
    padding: 10px;
    background-color: red;
    margin: 5px;
}

.product img {
    display: block;
    margin: 0 auto;
    max-height: 250px;
    max-width: 250px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div class="outer-wrapper">
<div class="products-wrapper">
      <div class="product">
          <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/St._Bernard_puppy.jpg/120px-St._Bernard_puppy.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/St._Bernard_puppy.jpg/120px-St._Bernard_puppy.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/St._Bernard_puppy.jpg/120px-St._Bernard_puppy.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
</div>
</div>
</body>
</html>
elyalvarado
  • 1,226
  • 8
  • 13
  • Like I said in my post, I have tried this. It will not horizontally align properly in a straight line depending on how much text there is in the

    .

    – Nifel Apr 22 '18 at 18:04
  • @Nifel, You need to use an additional wrapper flex to achieve what you want, look at my edited answer – elyalvarado Apr 22 '18 at 18:44
1

Make the .product element, flex container. This so you can align the content inside them.

.product {
    max-width: 250px;
    padding: 10px;
    display: flex;
    justify-content: center;
    flex-direction: column;
}

Hope this helps :)

.products-wrapper {
    width: 100%;
    min-height: 100vh;
    /* FLEX */
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-content: center;
}

.product {
    max-width: 250px;
    padding: 10px;
    display: flex;
    justify-content: center;
    flex-direction: column;
}

.product img {
    display: block;
    margin: 0 auto;
    max-height: 250px;
    max-width: 250px;
}
<div class="products-wrapper">
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
      <div class="product">
          <img src="images/temporary.jpg" alt="Temporary">
          <h3>Title</h3>
          <p>Text.</p>
      </div>
</div>
Gerardo BLANCO
  • 5,590
  • 1
  • 16
  • 35