Div horizontal alignment. Centering the div and other positioning subtleties

  • 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 using:

    • 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 indentation

    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.

    Centering elements vertically using CSS is a task that presents some difficulty for developers. However, there are several methods for solving it, which are quite simple. This lesson presents 6 options for vertically centering content.

    Let's start with a general description of the problem.

    Vertical Centering Problem

    Horizontal centering is very simple and easy. When the centered element is inline, we use the alignment property relative to the parent element. When the element is block-level, we set its width and automatic setting of left and right margins.

    Most people, when using the text-align: property, refer to the vertical-align property for vertical centering. Everything looks quite logical. If you've used table templates, you've probably made extensive use of the valign attribute, which reinforces the belief that vertical-align is the right way to solve the problem.

    But the valign attribute only works on table cells. And the vertical-align property is very similar to it. It also affects table cells and some inline elements.

    The value of the vertical-align property is relative to the parent inline element.

    • In a line of text, alignment is relative to the line height.
    • The table cell uses alignment relative to a value calculated by a special algorithm (usually the row height).

    But unfortunately, the vertical-align property does not work on block-level elements (for example, paragraphs inside a div element). This situation may lead one to believe that there is no solution to the vertical alignment problem.

    But there are other methods for centering block elements, the choice of which depends on what is being centered in relation to the outer container.

    Line-height method

    This method works when you want to center one line of text vertically. All you have to do is set the line height to be larger than the font size.

    By default, the white space will be distributed evenly at the top and bottom of the text. And the line will be centered vertically. Often the line height is made equal to the element height.

    HTML:

    Required text

    CSS:

    #child ( line-height: 200px; )

    This method works in all browsers, although it can only be used for one line. The value 200 px in the example was chosen arbitrarily. You can use any value larger than the text font size.

    Centering an Image Using Line-Height

    What if the content is a picture? Will the above method work? The answer lies in one more line of CSS code.

    HTML:

    CSS:

    #parent ( line-height: 200px; ) #parent img ( vertical-align: middle; )

    The value of the line-height property must be greater than the height of the image.

    CSS Table Method

    It was mentioned above that the vertical-align property is used for table cells, where it works great. We can display our element as a table cell and use the vertical-align property on it to vertically center the content.

    Note: A CSS table is not the same as an HTML table.

    HTML:

    Content

    CSS:

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

    We set the table output to the parent div element and output the nested div element as a table cell. You can now use the vertical-align property on the inner container. Everything in it will be centered vertically.

    Unlike the above method, in this case the content can be dynamic as the div element will change size according to its content.

    The disadvantage of this method is that it does not work in older versions of IE. You have to use the display: inline-block property for the nested container.

    Absolute positioning and negative margins

    This method also works in all browsers. But it requires that the element being centered be given a height.

    The example code performs horizontal and vertical centering at the same time:

    HTML:

    Content

    CSS:

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

    First, we set the element positioning type. Next, we set the nested div element's top and left properties to 50%, which corresponds to the center of the parent element. But the center is the top left corner of the nested element. Therefore, you need to lift it up (half the height) and move it to the left (half the width), and then the center will coincide with the center of the parent element. So knowing the height of the element in this case is necessary. Then we set the element with negative top and left margins equal to half the height and width, respectively.

    This method does not work in all browsers.

    Absolute positioning and stretching

    The example code performs vertical and horizontal centering.

    HTML:

    Content

    CSS:

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

    The idea behind this method is to stretch the nested element to all 4 borders of the parent element by setting the top, bottom, right, and left properties to 0.

    Setting the margin to auto-generate on all sides will set equal values ​​on all 4 sides and center our nested div element on its parent element.

    Unfortunately, this method does not work in IE7 and below.

    Equal spaces above and below

    In this method, equal padding is explicitly set above and below the parent element.

    HTML:

    Content

    CSS:

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

    The example CSS code sets top and bottom padding for both elements. For a nested element, setting the padding will serve to vertically center it. And the parent element's padding will center the nested element within it.

    Relative units of measurement are used to dynamically resize elements. And for absolute units of measurement you will have to do calculations.

    For example, if the parent element has a height of 400px and the nested element is 100px, then 150px of padding is needed at the top and bottom.

    150 + 150 + 100 = 400

    Using % allows you to leave the calculations to the browser.

    This method works everywhere. The downside is the need for calculations.

    Note: This method works by setting the outer padding of an element. You can also use margins within an element. The decision to use margins or padding must be made depending on the specifics of the project.

    floating div

    This method uses an empty div element that floats and helps control the position of our nested element in the document. Note that the floating div is placed before our nested element in the HTML code.

    HTML:

    Content

    CSS:

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

    We offset the empty div to the left or right and set its height to 50% of its parent element. This way it will fill the top half of the parent element.

    Since this div is floating, it is removed from the normal flow of the document, and we need to unwrap the text on the nested element. The example uses clear: both , but it is quite enough to use the same direction as the offset of a floating empty div element.

    The top border of a nested div element is directly below the bottom border of an empty div element. We need to move the nested element up by half the height of the floating empty element. To solve the problem, use a negative margin-bottom property value for a floating empty div element.

    This method also works in all browsers. However, using it requires an additional empty div element and knowledge of the height of the nested element.

    Conclusion

    All methods described are easy to use. The difficulty is that none of them are suitable for all cases. You need to analyze the project and choose the one that best suits the requirements.

    Vlad Merzhevich

    Due to the fact that the contents of table cells can be simultaneously aligned horizontally and vertically, the possibilities for controlling the position of elements relative to each other are expanded. Tables allow you to set the alignment of images, text, form fields, and other elements relative to each other and the web page as a whole. In general, alignment is mainly necessary to establish visual connections between different elements, as well as to group them together.

    Vertical centering

    One way to show the visitor the focus and name of the site is to use a splash page. This is the first page on which, as a rule, there is a flash splash screen or a picture expressing the main idea of ​​the site. The image is also a link to other sections of the site. You need to place this image in the center of the browser window, regardless of the monitor resolution. For this purpose, you can use a table with a width and height of 100% (example 1).

    Example 1: Centering the drawing

    Alignment

    In this example, horizontal alignment is set using the align="center" tag parameter , and the contents of the cell may not be centered vertically, since this is the default position.

    To set the table height to 100%, you need to remove, the code ceases to be valid.

    Using the width and height to cover the entire available area of ​​the web page ensures that the content of the table will be aligned exactly to the center of the browser window, regardless of its size.

    Horizontal alignment

    By combining the align (horizontal alignment) and valign (vertical alignment) attributes of the tag , it is permissible to set several types of positions of elements relative to each other. In Fig. Figure 1 shows ways to align elements horizontally.

    Let's look at some examples of text alignment according to the figure below.

    Top Alignment

    To specify the top alignment of cell contents, for a tag you need to set the valign attribute with the value top (example 2).

    Example 2: Using valign

    Alignment

    Column 1 Column 2

    In this example, cell characteristics are controlled using tag parameters , but it’s also more convenient to change through styles.

    In particular, the alignment in cells is specified by the vertical-align and text-align properties (example 3).

    Alignment

    Column 1 Column 2

    Example 3: Applying styles for alignment

    To shorten the code, this example uses grouping of selectors because the vertical-align and padding properties are applied to two cells at the same time.

    Bottom alignment is done in the same way, but instead of the top value, bottom is used.

    Center alignment

    In this case, the formula is located strictly in the center of the browser window, and its number is located on the right edge. To arrange elements in this way, you will need a table with three cells. The outermost cells should have the same dimensions, in the middle cell the alignment is done in the center, and in the right one - along the right edge (example 4). This number of cells is required to ensure that the formula is positioned in the center.

    Example 4: Formula Alignment

    Alignment

    (18.6)

    In this example, the first cell of the table is left empty; it serves only to create an indent, which, by the way, can also be set using styles.

    Aligning Form Elements

    Using tables, it is convenient to determine the position of form fields, especially when they are interspersed with text. One of the design options for the form, which is intended for entering a comment, is shown in Fig. 3.

    To ensure that the text next to the form fields is right-aligned and the form elements themselves are left-aligned, you will need a table with an invisible border and two columns. The left column will contain the text itself, and the right column will contain text fields (example 5).

    Example 5: Aligning Form Fields

    Alignment

    Name
    Email
    A comment

    In this example, for those cells where right alignment is required, the align="right" attribute is added.

    To ensure that the Comment label is positioned at the top of multiline text, the corresponding cell is set to top-aligned using the valign attribute.

    Very often the task is to align a block in the center of the page / screen, and even so that without a Java script, without setting rigid dimensions or negative indents, and so that the scrollbars work for the parent if the block exceeds its size. There are quite a lot of monotonous examples on the Internet on how to align a block to the center of the screen. As a rule, most of them are based on the same principles.

    Below are the main ways to solve the problem, their pros and cons. To understand the essence of the examples, I recommend reducing the height/width of the Result window in the examples at the links provided.

    Option 1: Negative indentation. Positioning block using the top and left attributes by 50%, and knowing the height and width of the block in advance, set a negative margin, which is equal to half the size block Positioning. A huge disadvantage of this option is that you need to count negative indents. Also

    Parent ( width: 100%; height: 100%; position: absolute; top: 0; left: 0; overflow: auto; ) .block ( width: 250px; height: 250px; position: absolute; top: 50%; left : 50%; margin: -125px 0 0 -125px; img (max-width: 100%; height: auto; display: block; margin: 0 auto; border: none; ) )

    Option 2. Automatic indentation.

    Less common, but similar to the first. For using the top and left attributes by 50%, and knowing the height and width of the block in advance, set a negative margin, which is equal to half the size we set the width and height, position the attributes top right bottom left to 0, and set margin auto. The advantage of this option is working scrollbars parent, if the latter has 100% width and height. The disadvantage of this method is the rigid setting of dimensions.

    Parent ( width: 100%; height: 100%; position: absolute; top: 0; left: 0; overflow: auto; ) .block ( width: 250px; height: 250px; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; img (max-width: 100%; height: auto; display: block; margin: 0 auto; border: none; )

    Option 3. Table.

    Let's ask parent table styles, cell parent Set the text alignment to center. A block we set the line block model. The disadvantages we get are not working scrollbars, and in general the aesthetics of table “emulation” are not.

    Parent ( width: 100%; height: 100%; display: table; position: absolute; top: 0; left: 0; > .inner ( display: table-cell; text-align: center; vertical-align: middle; ) ) .block ( display: inline-block; img ( display: block; border: none; ) )

    To add a scroll to this example, you will have to add one more element to the design.
    Example: jsfiddle.net/serdidg/fk5nqh52/3.

    Option 4. Pseudo-element.

    This option is devoid of all the problems listed in the previous methods, and also solves the original problems. The point is that parent set styles pseudo element before, namely 100% height, center alignment and inline block model. It’s the same with using the top and left attributes by 50%, and knowing the height and width of the block in advance, set a negative margin, which is equal to half the size a line block model is placed, centered. To Positioning didn't "fall" under pseudo element, when the dimensions of the first one are greater than parent, indicate parent white-space: nowrap and font-size: 0, after which using the top and left attributes by 50%, and knowing the height and width of the block in advance, set a negative margin, which is equal to half the size cancel these styles with the following - white-space: normal. In this example, font-size: 0 is needed to remove the resulting space between parent And block due to code formatting. The space can be removed in other ways, but it is considered best to simply avoid it.

    Parent ( width: 100%; height: 100%; position: absolute; top: 0; left: 0; overflow: auto; white-space: nowrap; text-align: center; font-size: 0; &:before ( height: 100%; display: inline-block; vertical-align: middle; content: ""; ; img (display: block; border: none; ) )

    Or, if you need the parent to take up only the height and width of the window, and not the entire page:

    Parent ( position: fixed; top: 0; right: 0; bottom: 0; left: 0; overflow: auto; white-space: nowrap; text-align: center; font-size: 0; &:before ( height: 100%; display: inline-block; vertical-align: middle; content: ""; ( display: block; border: none; ) )

    Option 5. Flexbox.

    One of the simplest and most elegant ways is to use flexbox. It does not require unnecessary body movements, quite clearly describes the essence of what is happening, and is highly flexible. The only thing worth remembering when choosing this method is support for IE from version 10 inclusive. caniuse.com/#feat=flexbox

    Parent ( width: 100%; height: 100%; position: fixed; top: 0; left: 0; display: flex; align-items: center; align-content: center; justify-content: center; overflow: auto; ) .block ( background: #60a839; img ( display: block; border: none; ) )

    Option 6. Transform.

    Suitable if we are limited by the structure, and there is no way to manipulate the parent element, but the block needs to be aligned somehow. The css function translate() will come to the rescue. A value of 50% absolute positioning will position the top left corner of the block exactly in the center, then a negative translate value will move the block relative to its own dimensions. Please note that negative effects may appear in the form of blurred edges or font style. Also, this method can lead to problems with calculating the position of the block using java-script. Sometimes, to compensate for the loss of 50% of the width due to the use of the CSS left property, the rule specified for the block can help: margin-right: -50%; .

    Parent ( width: 100%; height: 100%; position: fixed; top: 0; left: 0; overflow: auto; ) .block ( position: absolute; top: 50%; left: 50%; transform: translate( -50%, -50%); img (display: block; ) )

    Option 7. Button.

    User azproduction option where Positioning framed in a button tag. The button has the property of centering everything that is inside it, namely the elements of the inline and block-line (inline-block) model. In practice I do not recommend using it.

    Parent ( width: 100%; height: 100%; position: absolute; top: 0; left: 0; overflow: auto; background: none; border: none; outline: none; ) .block ( display: inline-block; img (display: block;; border: none; ) )

    Bonus

    Using the idea of ​​the 4th option, you can set external margins for using the top and left attributes by 50%, and knowing the height and width of the block in advance, set a negative margin, which is equal to half the size, and the latter will be adequately displayed surrounded by scrollbars.
    Example: jsfiddle.net/serdidg/nfqg9rza/2.

    You can also align the image to the center, and if the image is larger parent, scale it to size parent.
    Example: jsfiddle.net/serdidg/nfqg9rza/3.
    Example with a large picture: