Navigation menus using CSS flexbox
This tutorial will demonstrate different navigation menus using CSS flexbox. The CSS code provided in each of the demos below can be edited and modified for use on other app or web projects.
This project provides CSS examples and examples in SCSS!
The HTML markup for all examples illustrated below are identical as follow:
Base Example HTML
<nav>
<ul>
<li><a href="#" title="Home">Home</a></li>
<li><a href="#" title="Blog">Blog</a></li>
<li><a href="#" title="Work">Work</a></li>
<li><a href="#" title="Resources">Resources</a></li>
<li><a href="#" title="Meta">Meta</a></li>
</ul>
</nav>
Base CSS Styles
SCSS
ul {
border-bottom: 1px solid #ccc;
list-style: none;
margin: 0 0 1.5rem 0;
padding: 0;
}
li {
background-image: linear-gradient(
to bottom,
transparent 50%,
rgba(162,211,156, 1) 50%,
rgba(162,211,156,1) 95%,
rgba(124,197,118,1) 95%
);
background-size: 100% 200%;
background-position: top center;
color: #666;
display: block;
text-align: center;
text-decoration: none;
transition: all .25s ease-in-out;
&:hover {
background-position: bottom center;
color: rgba(0,0,0,.75);
}
& a {
color: #666;
display: block;
padding: 1rem 0;
transition: all .25s ease-in-out;
}
}
Compiled CSS
ul {
border-bottom: 1px solid #ccc;
list-style: none;
margin: 0 0 1.5rem 0;
padding: 0;
}
li {
background-image: linear-gradient(to bottom, transparent 50%, #a2d39c 50%, #a2d39c 95%, #7cc576 95%);
background-size: 100% 200%;
background-position: top center;
color: #666;
display: block;
text-align: center;
text-decoration: none;
transition: all 0.25s ease-in-out;
}
li:hover {
background-position: bottom center;
color: rgba(0, 0, 0, 0.75);
}
li a {
color: #666;
display: block;
padding: 1rem 0;
transition: all 0.25s ease-in-out;
}
About Project
Skew CSS Flexbox Navigation Example
Skew CSS Flexbox Navigation Example is an example of a HTML navigation menu using flexbox and CSS transform skew property.
Scenario 1
Equal width elements
This is the equivalent of specifying each element to be an equal fraction of its parent’s full width, i.e. each fraction is of identical size and the sum of their widths is equivalent to the parent’s full width.
This effect is achieved with the help of flex: 1 1 100%
on the flex items, which is a shorthand for:
flex-grow: 1;
flex-shrink: 1;
flex-basis: 100%
The property tells the browser to grow the items equally until they fill the full width of their flex parent, which is the <ul>
element in this case. The flex-basis
of 100% ensures that all items will be the same size and treated equally.
Of course, this effect can be easily replicated with the good old CSS float and percentage width trick, but this will require knowing the number of children beforehand, or else one will have to calculate the percentage width with JS instead.
More on positioning elements using CSS Floats.
SCSS
nav {
& ul {
display: flex;
width: 100%;
& li {
flex: 1 1 100%;
}
}
}
Compiled CSS
nav ul {
display: flex;
width: 100%;
}
nav ul li {
flex: 1 1 100%;
}
Scenario 2
Proportionate, content-based width:
In other words, the width of each element will be proportionate to its relative width compared to the parent. This ensures a more balanced layout in the sense that wider menu items get more spacing
Here, thanks to CSS Flexbox sizing, we use the property flex: 1 1 auto
on the children element. It is the shorthand of:
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
Like the previous example, flex-grow:
allows the children to grow when necessary, but on the condition that the width of each element is based on the size of its content. The latter is achieved with the help of:
SCSS
nav {
& ul {
display: flex;
width: 100%;
& li {
flex-grow: 1;
}
}
}
Compiled CSS
nav ul {
display: flex;
width: 100%;
}
nav ul li {
flex-grow: 1;
}
Scenario 3
Equally spaced elements + natural width + centered within parent:
This is one of the more complicated examples that require a lot of CSS-hacking — without the flexbox specification, one has to set each item to an inline element and then justify them.
The trick here is to declare the wrapping container, <nav>
, as well as the list itself, as flex displays — but we only apply the justify-content: center;
property to the HTML parent container.
SCSS
nav {
display: flex;
justify-content: center;
& ul {
display: flex;
& a {
padding: 1rem 2rem;
}
}
}
Compiled CSS
nav {
display: flex;
justify-content: center;
}
nav ul {
display: flex;
}
nav ul a {
padding: 1rem 2rem;
}
Fancy Example 1
Mixing flexbox with CSS transforms. This example uses the CSS transform property. The transform property is set to transform: skew(-15deg)
, which sets the <li>
element at a slant of 15 degrees.
SCSS
[id^='fun'] ul {
background-color: #eee;
border: 0;
display: flex;
padding: 0 2rem;
position: relative;
left: -2rem;
width: calc(100% + 4rem);
& li {
background-image: linear-gradient(
to bottom,
transparent 50%,
rgba(68,140,203, 1) 50%,
rgba(68,140,203,1) 95%,
rgba(0,114,188,1) 95%
);
flex: 1 1 auto;
& a:hover {
color: #eee;
}
}
}
#fun1 {
& ul li {
border-left: 2px solid #ddd;
transform: skew(-15deg);
&:last-child {
border-right: 2px solid #ddd;
}
& a {
transform: skew(15deg);
}
}
}
Compiled CSS
[id^=fun] ul {
background-color: #eee;
border: 0;
display: flex;
padding: 0 2rem;
position: relative;
left: -2rem;
width: calc(100% + 4rem);
}
[id^=fun] ul li {
background-image: linear-gradient(to bottom, transparent 50%, #448ccb 50%, #448ccb 95%, #0072bc 95%);
flex: 1 1 auto;
}
[id^=fun] ul li a:hover {
color: #eee;
}
#fun1 ul li {
border-left: 2px solid #ddd;
transform: skew(-15deg);
}
#fun1 ul li:last-child {
border-right: 2px solid #ddd;
}
#fun1 ul li a {
transform: skew(15deg);
}
Fancy Example 2
Mixing flexbox with CSS transforms:
SCSS
[id^='fun'] ul {
background-color: #eee;
border: 0;
display: flex;
padding: 0 2rem;
position: relative;
left: -2rem;
width: calc(100% + 4rem);
& li {
background-image: linear-gradient(
to bottom,
transparent 50%,
rgba(68,140,203, 1) 50%,
rgba(68,140,203,1) 95%,
rgba(0,114,188,1) 95%
);
flex: 1 1 auto;
& a:hover {
color: #eee;
}
}
}
#fun2 {
& li:hover {
transform: scale(1.2);
}
}
Compiled CSS
[id^=fun] ul {
background-color: #eee;
border: 0;
display: flex;
padding: 0 2rem;
position: relative;
left: -2rem;
width: calc(100% + 4rem);
}
[id^=fun] ul li {
background-image: linear-gradient(to bottom, transparent 50%, #444dcb 50%, #448ccb 95%, #0072bc 95%);
flex: 1 1 auto;
}
[id^=fun] ul li a:hover {
color: #eee;
}
#fun2 li:hover {
transform: scale(1.2);
}