Welcome to our free Introduction to CSS tutorial. This tutorial is based on Webucator's Introduction to CSS Training course.
CSS provides multiple layout systems that can be mixed and matched to give incredible control over the layout of your pages. We will be briefly looking at three of them:
Lesson Goals
The CSS Flexible Box Layout Module (or "Flexbox", as it's commonly known) offers a handy way to control the horizontal and vertical arrangement of elements on a page. As the W3C description (https://www.w3.org/TR/css-flexbox-1/#abstract) states:
In the flex layout model, the children of a flex container can be laid out in any direction, and can "flex" their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated.
Below are some common Flexbox properties:
Property | Explanation |
---|---|
display
|
To create flexible boxes, the display of the parent element of the elements you wish to turn into flexible boxes must be flex . |
flex-direction
|
flex-direction sets the direction of the flex container to be either horizontal or vertical. If it is horizontal the child flexible boxes are side by side. If it is vertical, the child flexible boxes are placed on top of each other. |
flex-wrap
|
flex-wrap sets whether or not the flexible boxes will wrap to a new line if they overflow their container. |
flex-flow
|
flex-flow is shorthand for flex-direction and flex-wrap . |
flex
|
flex is shorthand for the flex-grow , flex-shrink , and flex-basis properties and is used to set how flexible boxes take up the space of their container. |
Here are some further explanations with examples:
flex-flow
takes one value for either flex-direction
or flex-wrap
, or two values for both together (order doesn't matter).
Common flex-direction
values are:
row
- child flexible boxes are side by side.
column
- child flexible boxes are stacked on top of each other.
flex-direction
(https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction) also has takes row-reverse
and column-reverse
values to display the elements in reverse order.
Common flex-wrap
values are:
wrap
- Flexible boxes wrap if there is not enough space.
nowrap
- Flexible boxes extend outside of their container if there is not enough space.
flex-wrap
(https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap) also has takes a wrap-reverse
value to display the elements in reverse order.
These examples can be found in Layouts/Demos/flex-flow-examples.html.
flex
is shorthand for the flex-grow
, flex-shrink
, and flex-basis
properties, but generally just takes one of the following values:
initial
- The default value. The flexible box is sized by its width
and height
properties and shrinks to its minimum size to fit in its container.auto
- The flexible box is sized by its width
and height
properties, but grows to take up any extra space available in its container.none
- The flexible box is inflexible. It is sized by its width
and height
properties, but does not shrink or grow in relation to its container.flex
set to 1
and one with flex
set to 2
, then the box with flex: 2
will take up twice as much space as the other one.Below you can see a basic Flexbox demo:
body { background: aliceblue; } main { background: white; width: 98%; margin: auto; } section { border: 1px solid black; display: flex; flex-flow: row wrap; margin: 0.5rem auto; } section article { border: 1px solid black; border-radius: 0.5rem; flex: 1; padding: 0.5rem; margin: 0.5rem; min-width: 200px; } h2 { width: 100%; margin-left: 0.5rem; } section article:target { flex: 3; } section article:target h3 { text-decoration: underline; }
---- C O D E O M I T T E D ---- <body class="webucator"> <h1>Basic Flexbox</h1> <nav> <ol> <li><a href="#article1">Article 1</a></li> <li><a href="#article2">Article 2</a></li> <li><a href="#article3">Article 3</a></li> <li><a href="#article4">Article 4</a></li> <li><a href="#article5">Article 5</a></li> <li><a href="#article6">Article 6</a></li> </ol> </nav> <main> <section id="articles"> <h2>Articles</h2> <article id="article1"> <h3>Article 1</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article2"> <h3>Article 2</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article3"> <h3>Article 3</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article4"> <h3>Article 4</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article5"> <h3>Article 5</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article6"> <h3>Article 6</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> </section> </main> </body> </html>
The code above will render the following:
Some things to note:
article
s are the flexible boxes. They are set to be in rows and to wrap. They are set to have a flex
value of 1
by default. article
is given a flex
value of 3
. article1
is the target in this image.Grid offers a convenient, powerful method for laying out elements on a page. As the W3C specification states (https://www.w3.org/TR/css-grid-1/#abstract):
This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid.
Below are some common Grid properties:
Property | Explanation |
---|---|
display
|
To create a grid, the display of the parent element of the elements you wish to layout in a grid must be grid . |
grid-template-columns
|
grid-template-columns sets the size and number of columns in the grid container. |
grid-template-rows
|
grid-template-rows sets the size and number of rows in the grid container. |
grid-auto-columns
|
If grid-template-rows is used to create rows, then columns are generated implicitly (automatically). grid-auto-columns sets the size of these implicitly-generated columns if they are not explicitly defined by the grid-template-columns property. |
grid-auto-rows
|
If grid-template-columns is used to create rows, then rows are generated implicitly (automatically). grid-auto-rows sets the size of these implicitly-generated columns if they are not explicitly defined by the grid-template-rows property. |
gap
|
gap sets the space between rows and columns. |
grid-column
|
grid-column sets an element's horizontal position and size by specifying where it starts and ends along the columns in the grid container. |
grid-row
|
grid-row sets an element's vertical position and size by specifying where it starts and ends along the rows in the grid container. |
Here are some further explanations with examples:
Some common grid-template-columns
and grid-template-rows
values are:
200px
).30%
).fr
units (e.g., 3fr
) - Similar to the unitless values for Flexbox's flex
property. It specifies the proportion of space that the columns or rows take up.minmax(min, max)
(https://developer.mozilla.org/en-US/docs/Web/CSS/minmax) - Defines the size of the column or row ranging from the min
to the max
(e.g., minmax(100px, 1fr)
).repeat(number, size)
(https://developer.mozilla.org/en-US/docs/Web/CSS/repeat) - Creates the number
of columns or rows sized by the size
argument (e.g., repeat(5, 1fr)
).auto
- The element takes up the most space it can and doesn't shrink smaller than what is specified in min-width
and min-height
properties.The syntax of grid-template-columns
and grid-template-rows
is shown below:
grid-template-columns: column1, column2, column3, etc. grid-template-rows: row1, row2, row3, etc.
The following example creates a grid with a 40%
column, three 1fr
columns, and a 1fr
column that won't shrink below 150px
:
grid-template-columns: 40% repeat(3, 1fr) minmax(150px, 1fr);
The following example creates a grid with a 100px
row, three 1fr
rows, and a 3fr
row.
grid-template-rows: 100px repeat(3, 1fr) 3fr;
These examples can be found in Layouts/Demos/grid-examples.html.
grid-auto-columns
and grid-auto-rows
are very similar to grid-template-columns
and grid-template-rows
, but since they are targeting the implicitly-generated columns and rows, they only set size and not number.
Some common grid-auto-columns
and grid-auto-rows
values are:
200px
).30%
).fr
units (e.g., 3fr
) - Similar to the unitless values for Flexbox's flex
property. It specifies the proportion of space that the columns or rows take up.minmax(min, max)
(https://developer.mozilla.org/en-US/docs/Web/CSS/minmax) - Defines the size of the column or row ranging from the min
to the max
(e.g., minmax(100px, 1fr)
).auto
- The element takes up the most space it can and doesn't shrink smaller than what is specified in min-width
and min-height
properties.The following example sizes the implicit rows from our grid-template-columns
example:
grid-template-columns: 40% repeat(3, 1fr) minmax(150px, 1fr); grid-auto-rows: 50px;
The following example sizes the implicit columns from our grid-template-rows
example:
grid-template-rows: 100px repeat(3, 1fr) 3fr; grid-auto-columns: 75%;
These examples can be found in Layouts/Demos/grid-examples.html.
gap
specifies the space in between rows and columns. It takes one or two length or percentage values.
gap: 1rem
).gap: 1rem, 0.5rem
).Alternatively, the longhand
row-gap
(https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap) and
column-gap
(https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap) properties can be used.
The following example adds a 1rem
gap between rows and columns:
gap: 1rem; grid-template-columns: 40% repeat(3, 1fr) minmax(150px, 1fr);
The following example adds a 1rem
gap between rows and a 0.5rem
gap between columns:
gap: 1rem 0.5rem; grid-template-columns: 40% repeat(3, 1fr) minmax(150px, 1fr);
All the properties we have looked at so far are applied to the container grid element to create the grid. grid-column
and grid-row
are applied to the child elements and are used to size and position them within the grid. Both grid-column
and grid-row
take one or two values separated by a forward slash (/
).
These values use grid lines as references. Grid lines are numbered lines between the columns and rows.
See the image below to see the grid lines labeled on a basic grid:
Some common grid-column
and grid-row
values are:
grid-column: 1 / 3
sets the element to start at column line 1 and end at column line 3).span
keyword and unitless positive number specifying the number of columns or rows to span (e.g., grid-row: span 2 / -1
sets the element to span two rows and to end at row line -1).The following example gives Cell 1 a span of three and and makes it end at column line 5:
grid-columns: span 3 / 5;
The following example positions Cell 1 starting at row line 2 and ending the last row line (-1):
grid-row: 2 / -1;
These examples can be found in Layouts/Demos/grid-examples.html.
Below you can see a basic Grid Layout demo:
body { background: aliceblue; } main { background: white; display: grid; gap: 1rem 0.5rem; grid-template-columns: minmax(150px, 1fr) repeat(3, 1fr); grid-template-rows: repeat(3, 200px); margin: auto; min-width: 600px; padding: 0.5rem; width: 80%; } main nav { background: rgb(243, 241, 241); border: 1px solid black; border-radius: 0.5rem; font-size: 1.2rem; grid-column: 1 / 2; grid-row: 1 / -1; } article { border: 1px solid black; overflow: hidden; padding: 0.5rem; min-width: 100px; } article:target { border: solid black; grid-column: 2 / -1; grid-row: 1; } article:target h3 { text-decoration: underline; }
---- C O D E O M I T T E D ---- <body class="webucator"> <h1>Basic Grid Layout</h1> <main> <nav> <ol> <li><a href="#article1">Article 1</a></li> <li><a href="#article2">Article 2</a></li> <li><a href="#article3">Article 3</a></li> <li><a href="#article4">Article 4</a></li> <li><a href="#article5">Article 5</a></li> <li><a href="#article6">Article 6</a></li> <li><a href="#article7">Article 7</a></li> </ol> </nav> <article id="article1"> <h3>Article 1</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article2"> <h3>Article 2</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article3"> <h3>Article 3</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article4"> <h3>Article 4</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article5"> <h3>Article 5</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article6"> <h3>Article 6</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> <article id="article7"> <h3>Article 7</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique odio ac sem congue luctus. ---- C O D E O M I T T E D ---- </article> </main> </body> </html>
The code above will render the following:
Some things to note:
main
element is the grid container.article
is positioned at the top. article4
is the target in this image.Multi-column offers a way to organize content into columns. We can control the size and number of columns, the gap between columns, and an optional rule between columns. Listed below are the relevant properties.
Property | Explanation | Example/Possible Values |
---|---|---|
columns
|
Sets the width and count (number) of columns. |
columns: 10rem 2
|
column-fill
|
Sets how columns are populated with content. |
auto (fill columns sequentially) or balance (balance content as equally as possible). |
column-gap
|
Sets the size of the gap between columns. | A length value in units or normal , which is 1em for Multi-column. |
column-rule
|
Sets the width, style, and color of the rule (a line that separates columns). |
column: 0.2rem dashed red
|
break-inside
|
Sets whether or not an element can break inside itself. |
auto (can break) or avoid (avoids breaking). |
Unlike Flexbox and Grid, Multi-column is not meant to be used to create the entire layout of your web page. It is best to use it for collapsing small text elements like lists, or for creating masonry layouts. We do both in the following demo:
body { background: aliceblue; } main { background: white; margin: auto; min-width: 600px; width: 90%; } h2 { margin: 0.2rem auto; padding: 0.2rem; width: 256px; } nav { border: solid black; border-radius: 0.5rem; margin: auto; min-width: 550px; width: 90%; } nav ol { columns: 4; column-gap: 2rem; margin: 0.2rem auto; width: 90%; } div { background: rgb(235, 233, 233); box-sizing: border-box; break-inside: avoid; margin: 0 auto 1rem; padding: 0; } div a { display: block; width: 100%; } div img { width: 100%; transition: transform 0.5s; } div img:hover { transform: scale(0.95); transition: transform 0.5s; } #gallery { columns: 200px; column-fill: balance; column-gap: 0.5rem; margin: 1rem auto; width: 90%; } p.caption { font-size: 1.2rem; font-style: italic; margin: 0 1em; padding: 0 1em; }
---- C O D E O M I T T E D ---- <body class="webucator"> <h1>Multi-column</h1> <main> <h2>Check out our cute dogs!</h2> <nav> <ol> <li><a href="#dog1">Cute Dog 1</a></li> <li><a href="#dog2">Cute Dog 2</a></li> <li><a href="#dog3">Cute Dog 3</a></li> ---- C O D E O M I T T E D ---- <li><a href="#dog20">Cute Dog 20</a></li> </ol> </nav> <section id="gallery"> <div id="dog1"> <a href="#dog1"> <img src="images/dog1.jpg" alt="Cute Dog 1"></a> <p class="caption"> Here is one cute dog!</p> </div> <div id="dog2"> <a href="#dog2"> <img src="images/dog2.jpg" alt="Cute Dog 2"></a> <p class="caption"> And here's another one!</p> </div> <div id="dog3"> <a href="#dog3"> <img src="images/dog3.jpg" alt="Cute Dog 3"></a> <p class="caption"> So cute!</p> </div> ---- C O D E O M I T T E D ---- <div id="dog20"> <a href="#dog20"> <img src="images/dog20.jpg" alt="Cute Dog 20"></a> <p class="caption"> Mommy and baby. Adorable!</p> </div> </section> </main> </body> </html>
The above code will render the following:
Some things to note:
gallery section
will have as many 200px
columns as will fit. Making the window bigger creates room for more columns.In this exercise, you will continue to work with a new page that is part of the Running Blog.
You can design it however you like, or you can try to make it look something like:
---- C O D E O M I T T E D ---- main#photos { min-width: 620px; } #photos nav { margin: auto; min-width: 550px; width: 90%; } #photos nav ol { columns: 4; column-gap: 2rem; margin: 0.2rem auto; width: 90%; } #gallery { columns: 200px; column-fill: balance; column-gap: 0.5rem; margin: 1rem auto; width: 90%; } #gallery div { background: rgb(235, 233, 233); box-sizing: border-box; break-inside: avoid; margin: 0 auto 1rem; padding: 0; } #gallery div a { display: block; width: 100%; } #gallery div img { width: 100%; transition: transform 0.5s; } #gallery div img:hover { transform: scale(0.95); transition: transform 0.5s; } p.caption { font-size: 1.2rem; font-style: italic; margin: 0 1em; padding: 0 1em; } #gallery div:target { border: blue solid; } #gallery div:target p.caption { font-weight: bold; }
Some things to note:
running-shoes div
is the target in the screenshot.