Absolute horizontal and vertical centering. Horizontal and vertical alignment of elements in CSS

From the author: I welcome you again to the pages of our blog. In today's article I would like to talk about various alignment techniques that can be applied to both blocks and their content. In particular, how to align blocks in css, as well as text alignment.

Aligning blocks to the center

In CSS, centering a block is easy. This is the most well-known technique to many, but I would like to talk about it right now, first of all. This means horizontally centered alignment relative to the parent element. How is it done? Let's say we have a container and our experimental subject is in it:

< div id = "wrapper" >

< div id = "header" > < / div >

< / div >

Let's assume that this is the site header. It does not stretch across the entire width of the window and we need to center it. We write like this:

#header(

width / max - width : 800px ;

margin: 0 auto;

We need to specify the exact or maximum width, and then write down the key property - margin: 0 auto. It sets the outer margins of our header, the first value determines the top and bottom margins, and the second determines the right and left margins. The value auto tells the browser to automatically calculate padding on both sides so that the element is exactly centered in the parent. Comfortable!

Text alignment

This is also a very simple technique. To align all inline elements, you can use the text-align property and its values: left, right, center. The latter centers the text, which is what we need. You can even align a picture in the same way, because it is also an inline element by default.

Align text vertically

But this is more complicated. By default, there is no simple, well-known property that easily centers text vertically in a block container. However, there are several techniques that layout designers have come up with over the years.

Set the block height using padding. The way is not to set an explicit height using height, but to create it artificially using paddings at the top and bottom, which should be the same. Let's create any block and write the following properties to it:

div( background: #ccc; padding: 30px 0; )

div(

background : #ccc;

padding: 30px 0;

The background is just to visually show the edges as well as the padding. Now the height of the block is made up of these two indents and the line itself, and it all looks like this:

Define line-height for the block. I think this is a more correct way if you need to align one line of text. With it, you can write the height according to normal, using the height property. After that, he also needs to set the row height, the same as the height of the block as a whole.

div( height: 60px; line-height: 60px; )

div(

height: 60px;

line-height: 60px;

The result will be similar to the above picture. Everything will work even if you add padding. However, only for one line. If you need more text in the element, then this method will not work.

Convert a block to a table cell. The essence of this method is that the table cell has the vertical-align: middle property, which centers the element vertically. Accordingly, in this case the block needs to be set to the following:

div( display: table-cell; vertical-align: middle; )

div(

display: table - cell;

vertical - align: middle;

This method is good because you can align as much text as you like in the center. But it is better to write display: table to the block in which our div is nested, otherwise it may not work.

Well, here we come to the last technique for today - this is the vertical alignment of the blocks themselves. It must be said that, again, there is no property that would be intended specifically for this, but there are a few tricks that you should know about.

Set indents as a percentage. If you know the height of a parent element and place another block element inside it, you can center it using percentage padding. For example, the parent has a height of 600 pixels. You place a block in it that is 300 pixels high. How much do you need to back off at the top and bottom to center it? 150 pixels each, which is 25% of the parent’s height.

This method allows for alignment only when the dimensions allow for calculations. And if your parent is 887 pixels in height, then you won’t be able to accurately record anything, this is already clear.

Insert an element into a table cell. Again, if we transform the parent element into a table cell, then the block inserted into it will be automatically centered vertically. To do this, the parent just needs to set vertical-align: middle.

And if, in addition to this, we also write margin: 0 auto, then the element will become horizontally centered!

  • CSS
  • HTML
  • I think many of you who have had to deal with layout have encountered the need to align elements vertically and know the difficulties that arise when aligning an element to the center.

    Yes, there is a special multi-value vertical-align property in CSS for vertical alignment. However, in practice it doesn't work at all as expected. Let's try to figure this out.


    Let's compare the following approaches. Alignment with:

    • tables,
    • indentation,
    • line-height
    • stretching,
    • negative margin,
    • transform
    • pseudo element
    • flexbox.
    To illustrate, consider the following example.

    There are two div elements, with one of them nested within the other. Let's give them the corresponding classes - outer and inner.


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

    First, let's consider the case when the dimensions of the external and internal blocks known. Let's add the rule display: inline-block to the inner element, and text-align: center and vertical-align: middle to the outer element.

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

    Let's set the sizes of the blocks, as well as background colors so that we can 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 inner block is aligned horizontally, but not vertically:
    http://jsfiddle.net/c1bgfffq/

    Why did it happen? The thing is that the vertical-align property affects the alignment the element itself, not its contents(except when it is applied to table cells). Therefore, applying this property to the outer element did not produce anything. Moreover, applying this property to an inner element will also do nothing, since inline-blocks are aligned vertically relative to adjacent blocks, and in our case we have one inline block.

    There are several techniques to solve this problem. Below we will take a closer look at each of them.

    Alignment using a table

    The first solution that comes to mind is to replace the outer block with a table of one cell. In this case, the alignment will be applied to the contents of the cell, that is, to the inner block.


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

    The obvious disadvantage of this solution is that, from a semantic point of view, it is incorrect to use tables for alignment. The second disadvantage is that creating a table requires adding another element around the outer block.

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


    .outer-wrapper ( display: table; ) .outer ( display: table-cell; )
    However, the outer block will still remain a table with all the ensuing consequences.

    Alignment using indents

    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/

    The disadvantage of the solution is that it is applicable only in a limited number of cases when the heights of both blocks are known.

    Alignment using line-height

    If you know that the inner block should occupy no more than one line of text, then you can use the line-height property and set it equal to the height of the outer block. Since the content of the inner block should not wrap to the second line, it is recommended to also add the white-space: nowrap and overflow: hidden rules.

    Outer ( height: 200px; line-height: 200px; ) .inner ( white-space: nowrap; overflow: hidden; )
    http://jsfiddle.net/c1bgfffq/12/

    This technique can also be used to align multiline text if you redefine the line-height value for the inner block, and also add the display: inline-block and vertical-align: middle rules.

    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 external block must be known.

    Alignment using "stretch"

    This method can be used when the height of the external block is unknown, but the height of the internal block is known.

    To do this you need:

    1. set relative positioning to the external block, and absolute positioning to the internal block;
    2. add the rules top: 0 and bottom: 0 to the inner block, as a result of which it will stretch to the entire height of the outer block;
    3. set the vertical padding of the inner block to auto.
    .outer ( position: relative; ) .inner ( height: 100px; position: absolute; top: 0; bottom: 0; margin: auto 0; )
    http://jsfiddle.net/c1bgfffq/4/

    The idea behind this technique is that setting a height for a stretched and absolutely positioned block causes the browser to calculate the vertical padding in an equal ratio if it is set to auto .

    Alignment with negative margin-top

    This method has become widely known and is used very often. Like the previous one, it is used when the height of the outer block is unknown, but the height of the inner one is known.

    You need to set the external block to relative positioning, and the internal block to absolute positioning. Then you need to move the inner block down by half the height of the outer block top: 50% and raise it up by half its own height margin-top: -H inner / 2.

    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.

    Alignment with transform

    This method is similar to the previous one, but it can be used when the height of the indoor unit is unknown. In this case, instead of setting a negative pixel padding, you can use the transform property and move the inner 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 was it impossible to set the value as a percentage in the previous method? Since percentage margin values ​​are calculated relative to the parent element, a value of 50% would be half the height of the outer box, and we would need to raise the inner box to half its own height. The transform property is perfect for this.

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

    Alignment with Flexbox

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

    The outer block needs to be set to display: flex and the inner block to 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 method should I choose?

    You need to start from the problem statement:
    • To vertically align text, it is better to use vertical indents or the line-height property.
    • For absolutely positioned elements with a known height (for example, icons), the method with a negative margin-top property is ideal.
    • For more complex cases, when the height of the block is unknown, you need to use a pseudo element or the transform property.
    • Well, if you are so lucky that you do not need to support older versions of the IE browser, then, of course, it is better to use Flexbox.

    Aligning elements horizontally and vertically can be done in various ways. The choice of method depends on the type of element (block or inline), the type of its positioning, size, etc.

    1. Horizontal alignment to the center of the block/page

    1.1. If the block width is specified:

    div ( width: 300px; margin: 0 auto; /*center the element horizontally within the parent block*/ )

    If you want to align an inline element this way, it needs to be set to display: block;

    1.2. If a block is nested inside another block and its width is not specified/specified:

    .wrapper(text-align: center;)

    1.3. If the block has a width and needs to be centered on its parent block:

    .wrapper (position: relative; /*set relative positioning for the parent block so that we can then absolutely position the block inside it*/) .box ( width: 400px; position: absolute; left: 50%; margin-left: -200px; / *shift the block to the left by a distance equal to half its width*/ )

    1.4. If the blocks don't have a width specified, you can center them using a parent wrapper block:

    .wrapper (text-align: center; /*place the contents of the block in the center*/) .box ( display: inline-block; /*arrange the blocks in a row horizontally*/ margin-right: -0.25em; /*remove the right space between blocks*/ )

    2. Vertical alignment

    2.1. If the text occupies one line, for example, for buttons and menu items:

    .button ( height: 50px; line-height: 50px; )

    2.2. To vertically align a block within a parent block:

    .wrapper (position: relative;).box ( height: 100px; position: absolute; top: 50%; margin: -50px 0 0 0; )

    2.3. Vertical alignment by table type:

    .wrapper ( display: table; width: 100%; ) .box ( display: table-cell; height: 100px; text-align: center; vertical-align: middle; )

    2.4. If a block has a given width and height and needs to be centered on its parent block:

    .wrapper ( position: relative; ) .box ( height: 100px; width: 100px; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; overflow: auto; /*to the content did not spread */ )

    2.5. Absolute positioning at the center of the page/block using CSS3 transformation:

    if dimensions are specified for the element

    div ( width: 300px; /*set the width of the block*/ height:100px; /*set the height of the block*/ transform: translate(-50%, -50%); position: absolute; top: 50%; left: 50% ; )

    if the element has no dimensions and is not empty

    Some text here

    h1 ( margin: 0; transform: translate(-50%, -50%); position: absolute; top: 50%; left: 50%; )

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

    Yes, there is a special multi-value vertical-align property in CSS for vertical alignment. However, in practice it doesn't work at all as expected. Let's try to figure this out.


    Let's compare the following approaches. Alignment with:

    • tables,
    • indentation,
    • line-height
    • stretching,
    • negative margin,
    • transform
    • pseudo element
    • flexbox.
    To illustrate, consider the following example.

    There are two div elements, with one of them nested within the other. Let's give them the corresponding classes - outer and inner.


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

    First, let's consider the case when the dimensions of the external and internal blocks known. Let's add the rule display: inline-block to the inner element, and text-align: center and vertical-align: middle to the outer element.

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

    Let's set the sizes of the blocks, as well as background colors so that we can 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 inner block is aligned horizontally, but not vertically:
    http://jsfiddle.net/c1bgfffq/

    Why did it happen? The thing is that the vertical-align property affects the alignment the element itself, not its contents(except when it is applied to table cells). Therefore, applying this property to the outer element did not produce anything. Moreover, applying this property to an inner element will also do nothing, since inline-blocks are aligned vertically relative to adjacent blocks, and in our case we have one inline block.

    There are several techniques to solve this problem. Below we will take a closer look at each of them.

    Alignment using a table

    The first solution that comes to mind is to replace the outer block with a table of one cell. In this case, the alignment will be applied to the contents of the cell, that is, to the inner block.


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

    The obvious disadvantage of this solution is that, from a semantic point of view, it is incorrect to use tables for alignment. The second disadvantage is that creating a table requires adding another element around the outer block.

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


    .outer-wrapper ( display: table; ) .outer ( display: table-cell; )
    However, the outer block will still remain a table with all the ensuing consequences.

    Alignment using indents

    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/

    The disadvantage of the solution is that it is applicable only in a limited number of cases when the heights of both blocks are known.

    Alignment using line-height

    If you know that the inner block should occupy no more than one line of text, then you can use the line-height property and set it equal to the height of the outer block. Since the content of the inner block should not wrap to the second line, it is recommended to also add the white-space: nowrap and overflow: hidden rules.

    Outer ( height: 200px; line-height: 200px; ) .inner ( white-space: nowrap; overflow: hidden; )
    http://jsfiddle.net/c1bgfffq/12/

    This technique can also be used to align multiline text if you redefine the line-height value for the inner block, and also add the display: inline-block and vertical-align: middle rules.

    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 external block must be known.

    Alignment using "stretch"

    This method can be used when the height of the external block is unknown, but the height of the internal block is known.

    To do this you need:

    1. set relative positioning to the external block, and absolute positioning to the internal block;
    2. add the rules top: 0 and bottom: 0 to the inner block, as a result of which it will stretch to the entire height of the outer block;
    3. set the vertical padding of the inner block to auto.
    .outer ( position: relative; ) .inner ( height: 100px; position: absolute; top: 0; bottom: 0; margin: auto 0; )
    http://jsfiddle.net/c1bgfffq/4/

    The idea behind this technique is that setting a height for a stretched and absolutely positioned block causes the browser to calculate the vertical padding in an equal ratio if it is set to auto .

    Alignment with negative margin-top

    This method has become widely known and is used very often. Like the previous one, it is used when the height of the outer block is unknown, but the height of the inner one is known.

    You need to set the external block to relative positioning, and the internal block to absolute positioning. Then you need to move the inner block down by half the height of the outer block top: 50% and raise it up by half its own height margin-top: -H inner / 2.

    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.

    Alignment with transform

    This method is similar to the previous one, but it can be used when the height of the indoor unit is unknown. In this case, instead of setting a negative pixel padding, you can use the transform property and move the inner 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 was it impossible to set the value as a percentage in the previous method? Since percentage margin values ​​are calculated relative to the parent element, a value of 50% would be half the height of the outer box, and we would need to raise the inner box to half its own height. The transform property is perfect for this.

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

    Alignment with Flexbox

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

    The outer block needs to be set to display: flex and the inner block to 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 method should I choose?

    You need to start from the problem statement:
    • To vertically align text, it is better to use vertical indents or the line-height property.
    • For absolutely positioned elements with a known height (for example, icons), the method with a negative margin-top property is ideal.
    • For more complex cases, when the height of the block is unknown, you need to use a pseudo element or the transform property.
    • Well, if you are so lucky that you do not need to support older versions of the IE browser, then, of course, it is better to use Flexbox.

    Tags: Add tags

    A designer sometimes has a question: how to center elements vertically? And this causes certain problems. However, there are several methods for centering elements vertically, and each of these methods is quite simple. This article describes some of these methods.

    To see each method in action, click on the demo button or on the image.

    Let's discuss some of the issues that prevent vertical centering.

    Vertical-Align

    Horizontally centering an element is fairly easy to implement (using CSS). An inline element can be centered horizontally by giving its parent container a text-align property of center . When an element is a block element, to center it, you just need to set the width (width) and set the values ​​of the right (margin-right) and left (margin-left) margins to auto .

    Regarding text: many people are starting to use the vertical-align property for centering. It's logical and my first choice would be the same. To center an element in a table, you can use the valign attribute.

    However, the valign attribute only works when applied to a cell (for example, ). The CSS vertical-align property can be applied to a cell and some inline elements.

    • The text is centered relative to line-height (line spacing).
    • In relation to the table, without going into details, centering occurs relative to the height of the row.

    Unfortunately, the vertical-align property cannot be applied to block-level elements, such as a paragraph (p) inside a div tag.

    However, there are other methods for vertically centering elements, and you can still use the vertical-align property where needed. Which method to use depends on what you are going to center.

    Line spacing or Line-height

    This method should only be used when you need to center a line of text. To do this, you need to set the line-height (line spacing) of the element that contains text to greater than the font size.

    By default, there is equal space above and below the text, so the text is centered vertically.

    In this case, it is not necessary to specify the height of the parent element.

    Here's the text

    #child ( line-height: 200px; )

    This method works in all browsers, but do not forget that it should be used for a line of text. If your text spans more than one line, use a different method. The value of the line-height property can be anything, but not less than the font height. In practice, this method works great for centering a horizontal menu.

    CSS Method Using Table Properties

    As I already wrote, the contents of a cell can be centered using the CSS vertical-align property. The parent element must be represented as a table, the child element must be designated as a cell and the vertical-align property must be applied to it with the value middle . This way, any content in the child element will be centered vertically. The CSS code is given below.

    Content

    #parent ( display: table;) #child ( display: table-cell; vertical-align: middle; )

    Unfortunately, this method does not work in older versions of the IE browser. If you require browser support for IE6 and below, add a display: inline-block declaration to the child element.

    #child ( display: inline-block; )

    Absolute positioning and negative margin

    This method is designed for block-level elements and works in all browsers. You need to set the height of the element that needs to be centered.

    Below is the code where the child element is centered using this method.

    Content

    #parent (position: relative;) #child ( position: absolute; top: 50%; left: 50%; height: 30%; width: 50%; margin: -15% 0 0 -25%; )

    First you need to position the parent and child elements. We then set the child element's offset to 50% relative to the top and left side of the parent element, thereby centering the child element relative to the parent element. However, our manipulations will center the top-right corner of the child element in the center of the parent element, which, of course, does not suit us.

    Our task: to move the child element up and to the left, relative to the parent element, so that the child element is visually centered vertically and horizontally. This is why you need to know the height and width of the child element.

    So, we should give the child element a negative top and left margin equal to half, respectively, the width and height of the child element.

    Unlike the first two methods, this method is intended for block-level elements. The method works in all browsers, but the content may exceed the height of the parent element and extend beyond its boundaries. This method works best when the height and width of the elements are fixed.

    Absolute positioning of a child element

    As in the previous method, the parent and child elements are positioned relative and absolute, respectively.

    In the CSS code I center the child element both vertically and horizontally, however you can only use vertical centering.

    Content

    #parent (position: relative;) #child ( position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 50%; height: 30%; margin: auto; )

    The idea of ​​this method is that we can position a child element using top , left , right , bottom property values ​​equal to 0. Since our child element is smaller than the parent element, it will not be able to “stick” to the parent element.

    The margin values ​​for all four sides of the child element are zero, which centers the element vertically relative to the parent. Unfortunately, this method has the same disadvantages as the previous method: it is necessary to fix the height and width of the child, lack of support for older IE browsers.

    Bottom and top margins are equal

    In this method, we explicitly assign equal padding (bottom and top) to the parent element, which visually centers the child element vertically.

    Content

    #parent ( padding: 5% 0; ) #child ( padding: 10% 0; )

    I use relative sizes. If the block sizes are fixed, then you will need to do some mathematical calculations.

    For example, if the parent element has a height of 400px and the child is 100px, then you should set the top and bottom padding to 150px.

    150 + 150 + 100 = 400

    floating div

    This method involves an empty float block that controls the vertical position of the child element. The floating div needs to be placed before the child element, see the HTML code below.

    Content

    #parent (height: 250px;) #floater ( float: left; height: 50%; width: 100%; margin-bottom: -50px; ) #child ( clear: both; height: 100px; )

    First we move the floating block to the left (or right) and give it a height of 50% of its parent. This way the floating block will fill the top half of the parent element.

    Since the block is floating, it is removed from the general flow of the document, therefore, the child block should be assigned the clear property with the value both . I set the value to both , but you can use a value that matches the positioning direction of the floating element.

    Currently, the top edge of the child element lies directly below the bottom edge of the floating element. We need to raise the child element to half the height of the floating element. To do this, just set the negative bottom margin for the floating block to 50%.

    Works in all browsers. The disadvantage of this method is that it requires an empty block and requires knowing the height of the child element.