css3 – Flex, space-between and pseudo-elements

Question:

I work with display: flex and ran into such a problem. If you use the :before or :after pseudo- :after stretch blocks inside the parent via justify-content:space-between , then there is a side indent even if the element is in absolute position. Example:

div {
  position: relative;
  width: 200px;
  height: 100px;
  margin: 30px auto;
  background: #eee;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
div:after {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  height: 15px;
  background: #999;
}
<div><span>1</span><span>2</span></div>

It appears in Firefox, there are no problems in Chrome. I have not tested it on others. Is there a simple solution other than the obvious ones with float , wrapping in another block, etc. Thanks!

Answer:

So far, there is only one solution: do not use absolutely positioned elements inside a block with justify-content: space-between . To solve your problem with vertical alignment, I advise you these solutions:

6 ways to center an element of unknown size vertically and horizontally

Option number 1: table-cell

The oldest version, which was used at the dawn of the Internet and at the time of the dawn of table layout. For a long time, no one has typeset tables, but you can imitate their behavior through CSS in order to achieve a result:

.block {
   height: 380px; /* for Demo only */
   background: black; /* for Demo only */
   display: table;
   width: 100%;
}

.block-cell {
   display: table-cell;
   text-align: center;
   vertical-align: middle;
}
<div class="block">
   <div class="block-cell">
         <img src="https://1000.tech/img/team/01.jpg">
   </div>
</div>

Option # 2: position absolute

One of my favorite options. Ideal for positioning popups – they should be on top of the rest of the content, and their height is never known, like the user's screen height.

.block {
   height: 380px; /* for Demo only */
   background: black; /* for Demo only */
   position: relative;
}

.block img {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
}
<div class="block">
    <img src="https://1000.tech/img/team/01.jpg">
</div>

Option number 3: line-height

One of the stupidest options, which, although suitable for aligning a block of unknown height, requires a fixed parent height (in other methods, the parent's height is indicated only as an example). By the way, this method is also not suitable for multi-line text.

.block {
   background: black; /* for Demo only */
   line-height: 380px;
   text-align: center;
}

.block img {
   vertical-align: middle;
}
<div class="block">
   <img src="https://1000.tech/img/team/01.jpg">
</div>

Option # 4: centering through a pseudo-element

My favorite way. Despite the fact that I recently started using flexbox – alignment via pseudo-element will forever remain in my heart.

.block {
   height: 380px; /* for Demo only */
   background: black; /* for Demo only */
   text-align: center;
}

.block:before {
   content: '';
   height: 100%;
   display: inline-block;
   vertical-align: middle;
}

.block img {
   display: inline-block;
   vertical-align: middle;
}
<div class="block">
   <img src="https://1000.tech/img/team/01.jpg">
</div>

Option # 5: Flexbox

One of the modern and simplest centering methods is using display: flex .

.block {
   height: 380px; /* for Demo only */
   background: black; /* for Demo only */
   display: flex;
   align-items: center;
   justify-content: center;
}
<div class="block">
   <img src="https://1000.tech/img/team/01.jpg">
</div>

Option # 6: CSS Grid

Grid is our near and bright future! Aligning boxes has never been easier, and it is unlikely that anything will surpass CSS Grid anytime soon. Although this example is very similar to the previous one, the Grid is much more powerful. In general, if you haven't learned how to work with flexbox, you can safely skip it and deal with CSS Grid.

.block {
   height: 380px; /* for Demo only */
   background: black; /* for Demo only */
   display: grid;
   align-items: center;
   justify-content: center;
}
<div class="block">
   <img src="https://1000.tech/img/team/01.jpg">
</div>
Scroll to Top