Complex layouts using flex css examples. What is Flexbox? Description of all css properties, basic principles, advantages and disadvantages
![Complex layouts using flex css examples. What is Flexbox? Description of all css properties, basic principles, advantages and disadvantages](/uploads/31fffa23347dcadd1fd844ffec2e23a5.jpg)
Read also
Flexboxes are ideal for creating commonly used website layouts, such as the three-column, so-called “Holy Grail” layout, where all columns must be full height, regardless of their content. At the same time, in source code the main content comes before the navigation, and on the page itself the main content comes after the navigation.
Like this.
Before Flexbox, this layout was quite difficult to achieve without using some hacks. Developers often had to do things like add extra markup, apply negative margins, and other tricks to ensure everything would line up correctly regardless of the amount of content or screen size. But, as the example above shows, everything turns out much simpler on Flexbox.
Here's a summary of the code. In this example, we make the #main element a flex container, and leave the header and footer as block elements. In other words, only the middle part becomes flexbox. Here is a snippet that makes it a flex container.
#main ( display: flex; min-height: calc(100vh - 40vh); )
Just use display: flex to make a flex container. Note that we also set the min-height using the calc() function and set #main to 100% of the viewport height minus height of the header and base (20vh each). This ensures that the layout will fill the entire height of the screen, even if there is little content. As a result, the footer will never rise and leave empty space below it if the content takes up less than the height of the screen.
Calculating min-height was quite simple, given that we applied box-sizing: border-box to all elements. If we didn't do this, then we would need to add the padding value to the sum to subtract.
After installing the flex container, we deal with flex elements.
#main > article ( flex: 1; ) #main > nav, #main > aside ( flex: 0 0 20vw; background: beige; ) #main > nav ( order: -1; )
The flex property is shorthand for the flex-grow, flex-shrink, and flex-basis properties. In the first case, we only wrote one value, so flex sets the flex-grow property. In the second case, we wrote all three values for
The align-content property specifies the type of alignment of lines inside a flex container along the transverse axis if there is free space.
It applies to: flex container.
Default value: stretch.
Flex-start The lines are located at the beginning of the transverse axis. Each next line is flush with the previous one.
flex-end Rows are placed starting at the end of the cross axis. Each previous line is flush with the next.
center The lines are placed in the center of the container.
space-between The lines are evenly distributed in the container and the distance between them is the same. space-around The lines are evenly spaced so that the space between two adjacent lines is the same. The empty space before the first line and after the last line is equal to half the space between two adjacent lines.
space-evenly Rows are distributed evenly. The white space before the first line and after the last line is the same width as the other lines.: stretch.
Flex-start Lines are packed toward the start of the flex container. The cross-start edge of the first line in the flex container is placed flush with the cross-start edge of the flex container, and each subsequent line is placed flush with the preceding line.
Using the example of a form from a real test task, I will show you how to layout according to BEM using flexbox. You may ask: “Why is it necessary to typeset according to BEM + Flexbox?" This requirement comes from the employer. Quote from the statement of work: "Try to typesetting without frameworks (preferably on flexbox), simple and clear: avoid cumbersome structures and unnecessary code, use the methodology BEM."
Fragment of a section layout with a form
My layout rules
- Divide the layout into logical sections
- Start each section with a tag section
- Separate sections and CSS ruled from each other, empty line
- Assign a class to each tag
- The name of the class for a block or element, answers the question - What is this?
- The modifier name answers the question - Which?
HTML markup
First, I make the markup, determine the nesting of blocks and come up with names for classes. In the code below, we have two inline tags - h2 And input. Inline tags are a headache and a cause of stress for beginning layout designers. Why? They behave very badly - they try to take up the entire available width, and do not allow you to set the background color and dimensions of the entire block.
personal information
What does a bad layout designer do in this case? It wraps inline elements in block tags div and sets all the necessary properties to the wrapper tag. Child inline elements inherit these properties. Is it worth making a fuss of extra code? What would a competent layout designer do? It will redefine the inline element to block or inline-block, in CSS rules
Display: block; // for the input tag
display: inline-block; // for h2 tag
Nesting logic and block names
We see a section with personal information, so we call the section class - info. A section consists of three child elements:
Icon // class name info__icon
title // info__title
form // info__form
The point is in the names of the classes BEM, consists in the belonging of a child element to a parent. The element cannot be named icon. This is not just any icon, but an icon from the section info.
Daughter and parent rolled into one
Block info__form, we have a special one - it is nested in the section info, but at the same time, contains form fields. The name of this phenomenon is multi-level nesting. The block with the form has a purely wrapper function for inputs, so that you can easily set external margins. After all, lowercase inputs behave like children (which they are), they don’t obey at all. Moreover, the second input is shorter than all the others and differs only in width.
We set one class for all inputs with the same properties, except width - info__input. For regular inputs, add a modifier info__input_long, and the short input is given a modifier info__input_short. Let me remind you that the modifier BEM, should answer the question - Which?
CSS rules for modifiers
.info__input_long(width: 520px;
}
Info__input_short(
width: 320px;
}
CSS code
IN HTML markup creates a rough structure of the site, in CSS, we are already placing the elements according to the layout. Today, we will not touch on the appearance, but will focus on the positioning of elements. In our section, there are two flex containers. It must be said that the use of flexes, when all elements are located one at a time on a line, is very doubtful. The only benefit received is the property justify-content, center aligned, flex elements. I can say in my defense that the idea of flexes is pointless in the context of this section only. A real layout for layout usually has more variety.
Info (
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 77px;
height: 100%;
}
Info__form(
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
margin-top: 50px;
Flexbox can rightfully be called a successful attempt to solve a huge range of problems when building layouts in CSS. But before we move on to its description, let's find out what's wrong with the layout methods we use now?
Any layout designer knows several ways to align something vertically or make a 3-column layout with a rubbery middle column. But let's admit that all these methods are quite strange, look like a hack, are not suitable in all cases, are difficult to understand and do not work if certain magical conditions that have developed historically are not met.
This happened because html and css developed evolutionarily. At the beginning, web pages looked like single-threaded text documents, a little later, breaking the page into blocks was done with tables, then it became fashionable to layout with floats, and after the official death of ie6, inline-block techniques were also added. As a result, we inherited an explosive mixture of all these techniques, used to build layouts for 99.9% of all existing web pages.
Multi-line organization of blocks inside a flex container.
flex-wrap
All the examples that we gave above were built taking into account the single-line (single-column) arrangement of blocks. It must be said that by default, a flex container will always arrange the blocks inside itself in one line. However, the specification also supports multiline mode. The flex-wrap CSS property is responsible for multi-line content inside a flex container.
Available values flex-wrap:
- nowrap (default value): blocks are arranged in one line from left to right (in rtl from right to left)
- wrap: blocks are arranged in several horizontal rows (if they do not fit in one row). They follow each other from left to right (in rtl from right to left)
- wrap-reverse: same as wrap, but the blocks are arranged in the reverse order.
flex-flow is a convenient shorthand for flex-direction + flex-wrap
In essence, flex-flow provides the ability to describe the direction of the main and multi-line transverse axis in one property. Default flex-flow: row nowrap .
flex-flow:<‘flex-direction’> || <‘flex-wrap’>
CSS
/* i.e. ... */ .my-flex-block( flex-direcrion:column; flex-wrap: wrap; ) /* this is the same as... */ .my-flex-block( flex-flow: column wrap)align-content
There is also an align-content property, which determines how the resulting rows of blocks will be vertically aligned and how they will divide the entire space of the flex container.
Important: align-content only works in multi-line mode (i.e. in the case of flex-wrap:wrap; or flex-wrap:wrap-reverse;)
Available values align-content:
- flex-start: rows of blocks are pressed to the beginning of the flex container.
- flex-end: rows of blocks are pressed to the end of the flex container
- center: rows of blocks are in the center of the flex container
- space-between: the first row of blocks is located at the beginning of the flex container, the last row of blocks is at the end, all other rows are evenly distributed in the remaining space.
- space-around: rows of blocks are evenly distributed from the beginning to the end of the flex container, dividing all available space equally.
- stretch (default value): The rows of blocks are stretched out to take up all the available space.
The CSS properties flex-wrap and align-content should be applied directly to the flex container, not to its children.
Demo of multi-line properties in flex
CSS rules for child elements of a flex container (flex blocks)
flex-basis – the basic size of a single flex block
Sets the initial major axis size for a flex block before transformations based on other flex factors are applied to it. Can be specified in any length units (px, em, %, ...) or auto (default). If set as auto, the block dimensions (width, height) are taken as a basis, which, in turn, can depend on the size of the content, if not specified explicitly.
flex-grow – “greed” of a single flex block
Determines how much larger an individual flex block can be than adjacent elements, if necessary. flex-grow accepts a dimensionless value (default 0)
Example 1:
- If all flex boxes inside a flex container have flex-grow:1 then they will be the same size
- If one of them has flex-grow:2 then it will be 2 times larger than all the others
Example 2:
- If all flex boxes inside a flex container have flex-grow:3 then they will be the same size
- If one of them has flex-grow:12 then it will be 4 times larger than all the others
That is, the absolute value of flex-grow does not determine the exact width. It determines its degree of “greediness” in relation to other flex blocks of the same level.
flex-shrink – the “compressibility” factor of a single flex block
Determines how much the flex block will shrink relative to adjacent elements inside the flex container if there is not enough free space. Defaults to 1.
flex – shorthand for the flex-grow, flex-shrink and flex-basis properties
flex: none | [<"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]
CSS
/* i.e. ... */ .my-flex-block( flex-grow:12; flex-shrink:3; flex basis: 30em; ) /* this is the same as... */ .my-flex-block( flex: 12 3 30em )Demo for flex-grow, flex-shrink and flex-basis
align-self – alignment of a single flex block along the transverse axis.
Makes it possible to override the flex container's align-items property for an individual flex block.
Available align-self values (same 5 options as align-items)
- flex-start: the flex block is pressed to the beginning of the transverse axis
- flex-end: the flex block is pressed against the end of the cross axis
- center: flex block is located in the center of the cross axis
- baseline: flex block is aligned to baseline
- stretch (default value): The flex block is stretched to take up all available space along the cross axis, taking into account min-width / max-width if set.
order – the order of a single flex block inside a flex container.
By default, all blocks will follow each other in the order specified in the html. However, this order can be changed using the order property. It is specified as an integer and defaults to 0.
The order value does not specify the absolute position of the element in the sequence. It determines the weight of the element's position.
HTML
In this case, the blocks will follow one after another along the main axis in the following order: item5, item1, item3, item4, item2
Demo for align-self and order
margin: auto vertically. Dreams Come True!
You can love Flexbox at least because the familiar horizontal alignment via margin:auto works here for verticals too!
My-flex-container ( display: flex; height: 300px; /* Or whatever */ ) .my-flex-block ( width: 100px; /* Or whatever */ height: 100px; /* Or whatever * / margin: auto; /* Magic! The block is centered vertically and horizontally */ )
Things to Remember
- You should not use flexbox where it is not necessary.
- Defining regions and changing the order of content in many cases is still useful to make dependent on the page structure. Think it through.
- Understand flexbox and know the basics. This makes it much easier to achieve the expected result.
- Don't forget about margins. They are taken into account when setting axis alignment. It is also important to remember that margins in flexbox do not “collapse” as they do in a normal flow.
- The float value of flex blocks is not taken into account and has no meaning. This can probably somehow be used for graceful degradation when switching to flexbox.
- Flexbox is very well suited for the layout of web components and individual parts of web pages, but it has not shown its best side when laying out basic layouts (position of article, header, footer, navbar, etc.). This is still a controversial point, but this article shows the shortcomings quite convincingly xanthir.com/blog/b4580
Finally
I think that flexbox, of course, will not supplant all other layout methods, but, of course, in the near future it will occupy a worthy niche in solving a huge number of tasks. And of course, you need to try working with him now. One of the next articles will be devoted to specific examples working with flex layout. Subscribe to news;)
Nothing stands still, technologies and standards are developing, new techniques and methods for website layout are appearing, for example, layout with tabular elements, which we did not consider in objective reasons was replaced by layout with floating elements.
Many code editors have a convenient quick markup plugin built in or available for download by default, Emmet, which allows you to do the basic markup of this example as follows: section>div*3>lorem+ Tab (value lorem generates the text that appears in the image below).
Please note that without any special effort, we got the columns of our layout to be the same height regardless of their content, and this is great. Elements
are not flex elements by default and are located in the flow third element
The result of our example:
Inline flex container
By analogy with block elements, flex containers can be inline. Let's look at the difference between inline flex containers and block ones. In the previous example, we looked at the use of a block-level container, like a regular block-level element it occupies the entire width of the screen, and behaves like a regular block-level element. As for inline flex containers, they become regular inline elements, while maintaining the flexibility of the elements.
In the next example we will look at this difference, since the previous example would not be indicative, for the reason that the child flex elements were not explicitly given a size, and as a result, our container, whether it was inline or block, would behave the same and take up would be the entire width of the screen.
In this example we have placed two lowercase and two block flex containers, inside them we placed five elements
To quickly generate a similar layout using Emmet type the following in the editor: div.inline-flex*2>div*5 + Tab , and the same thing only with another class div.flex*2>div*5 + Tab .
Take a look at the result of our example, the difference between inline and block flex containers should now be obvious to you. An inline container behaves like an inline element and occupies the width required only by its child flex elements, while a block flex container, despite the size of its child flex elements, occupies the entire width of the screen.
The result of our example:
Rice. 205 An example of the difference between inline-flex containers and flex containers.
Direction? Which direction?
The direction of flex elements is formed based on the position of two axes: main axis flex container and its transverse axis, which is always located perpendicular to the main. Main axis in direction ltr (global HTML attribute dir , or the CSS direction property with the value ltr ) is located from left to right, and the cross one is from top to bottom (this is the default value), for the rtl value it is displayed in a mirror accordingly.