Flexbox Basics
CSS has long offered a number of layout modes for designing the layout of documents, text, tables, and positions. CSS Flexbox layout is a newer layout mode used to create responsive web page designs. It works in one-dimension at a time: rows or columns.
Introduction
CSS Flexbox includes the following properties:
flex-direction
sets the axis of the flex container. Options include:row
row-reverse
column
column-reverse
flex-wrap
defines whether flex container is single or multi-line. Options include:nowrap
(single line)wrap
(multi-line)wrap-reverse
flex-flow
is shorthand for:flex-direction
andflex-wrap
.- For example:
article { flex-flow: row wrap }
orsection { flex-flow: column nowrap}
.
- For example:
justify-content
works to align flex items (items in a flex container) along the main axis defined inflex-direction
. Options include:flex-start
: pack items at the line startflex-end
: pack items at the line endcenter
: pack items near the centerspace-between
: distribute items evenly across the line, placing first and last flex item near the each margin borderspace-around
: similar to above, but spaces first and last flex item a half space from each margin border
align-items
works on the cross axis of the container. Options include:flex-start
: flex items are flushed against the start of the containerflex-end
: flex items are flushed against the end of the containerbaseline
: the baselines of flex items are alignedstretch
: flex items are stretched from start to end
align-content
is similarly to howjustify-content
works on the main axis but works on the cross axis when there is extra space. Takes effect when their are multiple lines of items, such as whenflex-wrap: wrap
is in effect. Options include:flex-start
: pack items at the container startflex-end
: pack items at the container endcenter
: pack items near the center of the containerspace-between
: distribute items evenly in the flex container, placing first and last flex item near the each margin borderspace-around
: similar to above, but spaces first and last flex item a half space from each margin borderstretch
: flex items are stretched from start to end
Note how some properties above refer to the main axis or the cross axis.
- to use on main axis properties:
justify-content
- to use on cross axis properties:
align-items
align-content
By default, the main axis is the x-axis, and the cross axis is the y-axis.
Examples
To initiate a flex layout, we use the display
property.
We can use the display
property in section elements such as <body>
, <article>
, <section>
, <nav>
, <div>
, etc.
These elements become flex containers.
The flex items in these containers is thus any direct child element of a flex container.
For example, to create a flex container for the <nav>
element, we could use the following CSS declaration:
nav {
display: flex;
flex-flow: column wrap;
}
The elements in that <nav>
section, such as an unordered list <ul>
, become the container's flex items.
To create nested layouts, we can use display
multiple times in a single web page.
For example, if an <article>
element contains several <section>
elements, then the following would be used:
article {
display: flex;
flex-flow: column nowrap;
}
section {
display: flex;
flex-flow: row wrap;
}
Basic Flex Example
In the following example, I make the <section>
element a flex container.
This element includes six <p>
elements, which become the flex items.
The gap
property in the section
rule adds a 10px
gap between between flex items.
For the <p>
element, I add borders and expand their dimensions to create boxes around these elements.
I use a structural pseudo class nth-child()
to alternate the colors of these boxes.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex Example</title>
<style>
html {
font-size: 100%;
}
header {
border-bottom: 10px dotted blue;
}
section {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
p {
border: 1px solid black;
font-size: 2rem;
width: 8rem;
height: 8rem;
padding: 10rem;
}
p:nth-child(odd) {
background-color: black;
color: white;
}
p:nth-child(even) {
background-color: yellow;
color: black;
}
footer {
border-top: 10px dotted blue;
}
</style>
</head>
<body>
<header><h1>This is a title</h1></header>
<section>
<p>Box 1</p>
<p>Box 2</p>
<p>Box 3</p>
<p>Box 4</p>
<p>Box 5</p>
<p>Box 6</p>
</section>
<footer><h2>This is a footer</h2></footer>
</body>
</html>
Two Column Example
In the following example, I create a basic two-column layout.
The HTML of the page contains a <section>
element with two <article>
elements.
In the CSS, I make the <section>
element the flex container.
Since this element has the two <article>
elements as child elements,
the <article>
elements become flex items.
The items are wrapped (flex-flow
) to make them responsive.
And justify-content
is used to center the items within the <section>
container.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex Example: Two Column Layout</title>
<style>
html {
font-size: 100%;
}
header {
border-bottom: 2px black solid;
text-align: center;
}
section {
display: flex;
gap: 50px;
flex-flow: row wrap;
justify-content: center;
}
article {
margin: auto;
}
footer {
border-top: 2px black solid;
text-align: center;
}
</style>
</head>
<body>
<header><h1>Main Title</h1></header>
<section>
<article>
<h2>Article Title 1</h2>
<p>This is some text.</p>
</article>
<article>
<h2>Article Title 2</h2>
<p>This is more text.</p>
</article>
</section>
<footer><h2>This is a footer</h2></footer>
</body>
</html>
Mixed Columns
In the following example, I add an additional row that isn't a flex container. The result is a top row that contains two columns and an additional single column row. I make several other changes to augment the look of the page. These include:
I add the following to the body
selector to make the margins flush with the browser window:
body {
max-width: 100%;
margin: auto;
}
I create a nav
section and make it a flex container.
The result is a responsive navigation bar.
The <nav>
element includes an unordered list.
I remove the bullets in this list to make the list's appearance more conventional for a navigation section.
nav ul {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
background-color: black;
color: white;
padding: 10px;
list-style-position: inside;
}
nav ul li {
list-style-type: none;
}
Next comes the first of two <section>
elements in the web document.
I assign the first <section>
element to a class called main
to indicate that this is the main section,
and to differentiate it from the second <section>
element.
In the CSS, I make the main section a flex container.
I use flex-flow: row wrap
to make it a responsive row, and I use justify-content: center;
to center it on the main axis.
.main {
display: flex;
gap: 10px;
flex-flow: row wrap;
justify-content: center;
}
The remaining styles in the CSS control help keep the page consistent with the rest of the styling.
Note the use of the clamp()
function.
This is used to set the minimum, preferred, and maximum values of an element.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex Example: Mixed Column Layout</title>
<style>
html {
font-size: 100%;
font-family: monospace;
}
body {
max-width: 100%;
margin: auto;
font-size: 1.5rem;
}
header {
border-bottom: 2px black solid;
text-align: center;
}
nav ul {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
background-color: black;
color: white;
padding: 10px;
list-style-position: inside;
}
nav ul li {
list-style-type: none;
}
.main {
display: flex;
gap: 10px;
flex-flow: row wrap;
justify-content: center;
}
.main_article {
margin: auto;
max-width: clamp(320px, 40%, 1000px);
}
.secondary_article {
margin: auto;
max-width: clamp(320px, 40%, 1000px);
}
footer {
border-top: 2px black solid;
text-align: center;
}
</style>
</head>
<body>
<header>
<h1>Main Title</h1>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Blog</li>
</ul>
</nav>
</header>
<section class="main">
<article class="main_article">
<h2>Article Title 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</article>
<article class="main_article">
<h2>Article Title 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt.</p>
</article>
</section>
<section>
<article class="secondary_article">
<h2>Article Title 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt.</p>
</article>
</section>
<footer><h2>This is a footer</h2></footer>
</body>
</html>
Conclusion
In this section we learned about the CSS Flexbox layout model. I first detailed the CSS properties that are available to create a Flex layout. I provided an example using basic boxes. Then I created a two-column example and a mixed column example, both of which are responsive to mobile views. These may also be adapted to create more complex layouts.
Note that the use of Flex aligns well with section elements,
such as the <article>
, <section>
, <main>
, elements.
This is because, by definition, these elements are container elements.
Additional sources: