Layout Mechanisms and Flexbox
Learning objectives
- Knows one meaning for the term layout.
- Knows about the existence of non-visible HTML elements.
- Knows how non-visible HTML elements can be used to aid in defining styles.
- Knows the Flexbox-model and knows how to define the layout of elements using the Flexbox-models.
- Knows of the existence of other layout models.
Layout refers to visual structure of the page and how the elements on a page are arranged. We will next look into one particular approach for arranging elements on a page.
Non-visible HTML elements
HTML documents can contain HTML elements that are not visible to the user, but that describe the structure or content of the page. Most relevant of these elements are header
, section
, and footer
. The element header
is used for creating a header area for the page, the element section
is used for creating a logical entity (section) on the page, and the element footer
is used for creating a footer area for the page.
The example below shows a page that uses all of the three elements described above.
<!DOCTYPE html>
<html>
<head>
<title>Learning diary!</title>
</head>
<body>
<header>
<h1>Learning diary!</h1>
</header>
<section>
<h2>CSS</h2>
<p>I practiced using styles today..</p>
</section>
<section>
<h2>HTML</h2>
<p>Previously, I played aroud with HTML documents..</p>
</section>
<footer>
<p>My learning diary: ∞</p>
</footer>
</body>
</html>
The elements that are used to describe the structure of the page are not visible to the user. The way how the above page would look like to the user is shown below.
The elements header
, section
, and footer
can be used for clarifying the page structure and for styling. For example, the header could have a specific style, the sections could have a specific style, and the footer could have a specific style. The example below sets colors for the header and footer.
header {
background-color: lightblue;
}
footer {
background-color: black;
color: white;
}
If the page has an area, that is not related to a clear logical entity or does not have a clear role, but that we would still wish to style, we use the div
element. The div
element functions similarly to the header
, section
, and footer
, but it does not have a semantic meaning.
Element layout using Flexbox
CSS has multiple ways for creating layouts. Here, we look into one of them -- the Flexbox-model. We start with a situation where we have a div
element that contains four elements, each of them with a number. We have added an identifier container
to the div
element that contains the four elements.
<!DOCTYPE html>
<html>
<head>
<title>Flexbox</title>
</head>
<body>
<div id="container">
<div>
1
</div>
<div>
2
</div>
<div>
3
</div>
<div>
4
</div>
</div>
</body>
</html>
When viewed in a browser, the page looks as follows.
By default, a div
element (similar to header
, section
, and footer
) is shown so that the element occupies the whole row. This stems from the specific elements having a default display style, which is display: block;
.
Taking CSS Flexible Box Layout (Flexbox) model into use is done by setting a display style display: flex;
to the element that will contain the elements that we wish to show. We set the style to the element that is identified by the id container
.
#container {
display: flex;
}
Now, the page looks as follows.
As you notice, instead of placing each element into their own rows, the elements are placed next to each other. The same effect could have been reached by defining a style display: inline;
to each element. The important part in using the style display: flex;
is that it enables using other styles from the Flexbox model.
Direction and placing
Next, we look into the direction and spacing of the elements in the Flexbox-model. The direction into which the elements are placed is defined using the style flex-direction
. The value column
sets each element on its own line, while the value row
sets each element on the same line. Both of these values have a reverse version -- column-reverse
and row-reverse
. The example below uses row-reverse
as the value for the flex-direction
style.
#container {
display: flex;
flex-direction: row-reverse;
}
Placing and partially spacing of the elements is done using the style justify-content
. The style defines where elements should be placed and how they are justified. The value flex-start
(default setting) places the elements at the beginning of the containing element, while flex-end
places the elements at the end of the containing element. The value center
places the elements in the middle of the element. The style space-around
defines the distance between each element and the border the same, while space-between
works similarly to the space-around
but does not use a distance from the border.
Below, we have two examples from using these. The first example uses the style justify-content: flex-end;
, and the second example uses the style justify-content: space-around;
.
#container {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
#container {
display: flex;
flex-direction: row;
justify-content: space-around;
}
Question not found or loading of the question is still in progress.
Space for elements
The space that is reserved for an element is determined by default based on the element content. We typically wish to leave some "breathing room" for the elements. Such space is defined using the styles margin
and padding
, which receive a value that defines the amount of space that the elements should have.
The style margin
defines the space outside the element and the style padding
defines the space inside the element. The following example shows these -- the green area is margin while the blue area is padding. In the example below, both the margin and padding has been set to 20 pixels.
Let us look into using margin
and padding
with the example using Flexbox. The example has a container that contains four elements. Each of these elements have a number. The styles are defined so that the elements are placed on the same row and the distance between the elements is the same.
<div id="container">
<div>
1
</div>
<div>
2
</div>
<div>
3
</div>
<div>
4
</div>
</div>
#container {
display: flex;
flex-direction: row;
justify-content: space-around;
}
Next, we will add style classes to the elements that contain the numbers. The style classes will be red
and blue
. The class red will have a red background color and a padding of 0.5rem
. The class blue will have a light blue as the background and a padding of 1rem
. We will use the class red for the elements with the numbers 2 and 3, and the class blue for the elements with the numbers 1 and 4.
#container {
display: flex;
flex-direction: row;
justify-content: space-around;
}
.red {
padding: 0.5rem;
background-color: red;
}
.blue {
padding: 1rem;
background-color: lightblue;
}
<div id="container">
<div class="blue">
1
</div>
<div class="red">
2
</div>
<div class="red">
3
</div>
<div class="blue">
4
</div>
</div>
When we look at the example above, we notice that the height of all of the elements is the same. Let us change the vertical placing of the elements by using the style align-items
from the flexbox model. The default value for the style is stretch
, which sets the same height to all the elements.
Other possible values are flex-start
, flex-end
, center
and baseline
. The style flex-start
sets the elements to the top, flex-end
to the bottom, and center
to the middle. The value baseline
basically works similarly to center
. In the example below, we use the value flex-start
for align-items
. Now the elements are placed vertically at the top. We also notice that the height of the elements within the container is now defined based on the size of the elements.
#container {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: flex-start;
}
.red {
padding: 0.5rem;
background-color: red;
}
.blue {
padding: 1rem;
background-color: lightblue;
}
Increasing number of elements
Next, we look into a situation where the number of elements increases. In the example below, we use the value space-between
for the style justify-content
. This means that the space between the elements is the same and the elements are connected to the borders (i.e. there is no space between the elements and the borders). In addition, the container has some padding. The HTML document is the same as the one seen previously, but now the container has fifteen elements instead of four.
#container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
padding: 1rem;
}
.red {
padding: 0.5rem;
background-color: red;
}
.blue {
padding: 1rem;
background-color: lightblue;
}
As we observe above, all the elements do not fit on the screen. This leads to a bar being added at the bottom of the page, which allows the user to scroll sideways.
The Flexbox model allows choosing whether to use a scroll-bar or whether the overflowing elements should be placed on a new row. This is done using the style flex-wrap
. The value nowrap
is the default value that leads to the emergence of a scroll bar if the elements overflow. The value wrap
, on the other hand, would lead to the overflowing elements being placed on the subsequent rows.
Let us add the flex-wrap: wrap
to the style definition.
#container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
padding: 1rem;
flex-wrap: wrap;
}
.red {
padding: 0.5rem;
background-color: red;
}
.blue {
padding: 1rem;
background-color: lightblue;
}
Now, the elements will overflow to the next rows if needed.
Other layout models
We just practiced using the Flexbox model for setting the web page layout. In addition to the Flexbox model, one can use, for example, the Grid layout, which makes it possible to divide the screen into areas (that resemble a grid).