📜 ⬆️ ⬇️

All vertical alignment methods in CSS

image

I think many of you who have had to deal with the layout, faced with the need to align elements vertically and know what difficulties arise when aligning an element in the center.

Yes, for vertical alignment, CSS has a special vertical-align property with a lot of values . However, in practice, it does not work as expected. Let's try to figure it out.
')

Compare the following approaches. Alignment with:


As an illustration, consider the following example.

image

There are two div elements, one being nested within the other. We give them the corresponding classes - outer and inner .

 <div class="outer"> <div class="inner"></div> </div> 

The challenge is to align the inner element with the center of the outer element.

To begin with, consider the case when the dimensions of the external and internal units are known . Add the display: inline-block rule to the inner element, and text-align: center and vertical-align: middle outer element.

Remember that alignment applies only to elements that have an inline or inline-block display mode.

Let's set the size of the blocks, as well as the background colors to see their borders.

 .outer { width: 200px; height: 200px; text-align: center; vertical-align: middle; background-color: #ffc; } .inner { display: inline-block; width: 100px; height: 100px; background-color: #fcc; } 

After applying the styles, we will see that the indoor unit is horizontally aligned, but not vertically:
http://jsfiddle.net/c1bgfffq/

Why did it happen? The fact is that the vertical-align property affects the alignment of the element itself, and not its content (unless it is applied to table cells). Therefore, the application of this property to the external element gave nothing. Moreover, the application of this property to the inner element also does nothing, since the inline-block blocks are aligned vertically with respect to the neighboring blocks, and in our case we have one line block.

To solve this problem, there are several techniques. Below we take a closer look at each of them.

Table alignment


The first solution that comes to mind is to replace the external block with a table from a single cell. In this case, the alignment will be applied to the contents of the cell, that is, to the internal block.

 <table class="outer-wrapper"> <td class="outer"> <div class="inner"></div> </td> </table> 

http://jsfiddle.net/c1bgfffq/1/

The obvious disadvantage of this solution is that from the point of view of semantics it is wrong to use tables for alignment. The second disadvantage is that to create a table, you need to add another element around the external block.

The first minus can be partially removed by replacing the table and td tags with a div and setting the table display mode in CSS.

 <div class="outer-wrapper"> <div class="outer"> <div class="inner"></div> </div> </div> 

 .outer-wrapper { display: table; } .outer { display: table-cell; } 

Nevertheless, the external block will still remain a table with all the ensuing consequences.

Indent alignment


If the heights of the inner and outer blocks are known, then the alignment can be set using the vertical indents of the inner block using the formula: (H outer - H inner ) / 2.

 .outer { height: 200px; } .inner { height: 100px; margin: 50px 0; } 

http://jsfiddle.net/c1bgfffq/6/

Minus solution - it is applicable only in a limited number of cases when the heights of both blocks are known.

Alignment with line-height


If it is known that the internal block should occupy no more than one line of text, then you can use the line-height and set it equal to the height of the external block. Since the content of the indoor unit should not be transferred to the second line, it is recommended to also add the rules white-space: nowrap and overflow: hidden .

 .outer { height: 200px; line-height: 200px; } .inner { white-space: nowrap; overflow: hidden; } 

http://jsfiddle.net/c1bgfffq/12/

Also, this technique can be used to align multiline text, if for the indoor unit to override the value of line-height , as well as add display: inline-block rules display: inline-block and vertical-align: middle .

 .outer { height: 200px; line-height: 200px; } .inner { line-height: normal; display: inline-block; vertical-align: middle; } 

http://jsfiddle.net/c1bgfffq/15/

The disadvantage of this method is that the height of the outdoor unit must be known.

Alignment with Stretch


This method can be applied when the height of the external unit is unknown, but the height of the internal one is known.

For this you need:

  1. set relative positioning to the external block, absolute positioning to the internal block;
  2. add top: 0 and bottom: 0 rules to the internal block, as a result of which it will stretch to the entire height of the external block;
  3. set the auto value for the vertical indents of the indoor unit.

 .outer { position: relative; } .inner { height: 100px; position: absolute; top: 0; bottom: 0; margin: auto 0; } 

http://jsfiddle.net/c1bgfffq/4/

The essence of this technique is that setting the height for a stretched and absolutely positioned block causes the browser to calculate vertical indents in an equal ratio if their value is set to auto .

http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-height

The disadvantage of this method is that the height of the indoor unit must be known.

Alignment with a negative margin-top


This method is widely known and is used very often. Like the previous one, it is used when the height of the external unit is unknown, but the height of the internal one is known.

It is necessary to specify relative positioning for the external block, and absolute positioning for the internal block. Then you need to move the internal block down half the height of the external block top: 50% and raise the margin-top : -H inner / 2 up half of its own height.

 .outer { position: relative; } .inner { height: 100px; position: absolute; top: 50%; margin-top: -50px; } 

http://jsfiddle.net/c1bgfffq/13/

The disadvantage of this method is that the height of the indoor unit must be known.

Transform alignment


This method is similar to the previous one, but it can be applied when the height of the indoor unit is unknown. In this case, instead of setting a negative indentation in pixels, you can use the transform property and raise the internal block up using the translateY function and a value of -50% .

 .outer { position: relative; } .inner { position: absolute; top: 50%; transform: translateY(-50%); } 

http://jsfiddle.net/c1bgfffq/9/

Why in the previous method it was impossible to set the value in percent? Since the percentage values ​​of the margin property are calculated relative to the parent element, a value of 50% would be equal to half the height of the external block, and we had to raise the internal block by half of its own height. The transform property is just suitable for this.

The disadvantage of this method is limited support for the transform property by older versions of IE browser.

Alignment with pseudo-element


This is the most universal method that can be used when the heights of both blocks are unknown.

The essence of the method is to add a line block inline-block with a height of 100% inside the outer block and set it to vertical alignment. In this case, the height of the added block will be equal to the height of the external block. The inner block is aligned vertically with respect to the added, and hence the outer block.

In order not to violate the semantics, it is recommended to add a line block using a pseudo-element before or after .

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

http://jsfiddle.net/c1bgfffq/10/

The disadvantage of this method is that it cannot be applied if the indoor unit has absolute positioning.

Align with Flexbox


The most modern method of vertical alignment is to use the Flexible Box Layout (popularly known as Flexbox ). This module allows you to flexibly control the positioning of elements on the page, placing them almost as you like. Aligning to the center for Flexbox is a very simple task.

The external block needs to set display: flex , and the internal block - margin: auto . And it's all! Beautiful, is not it?

 .outer { display: flex; width: 200px; height: 200px; } .inner { width: 100px; margin: auto; } 

http://jsfiddle.net/c1bgfffq/14/

The disadvantage of this method is that Flexbox is supported only by modern browsers.

Which way to choose?


It is necessary to proceed from the statement of the problem:

Source: https://habr.com/ru/post/277433/


All Articles