惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
AI
AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
WordPress大学
WordPress大学
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
F
Full Disclosure
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security
Recorded Future
Recorded Future
N
News and Events Feed by Topic
雷峰网
雷峰网
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Project Zero
Project Zero
罗磊的独立博客
G
GRAHAM CLULEY
腾讯CDC
P
Privacy International News Feed
V
V2EX
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
H
Heimdal Security Blog
L
LINUX DO - 热门话题
Forbes - Security
Forbes - Security
美团技术团队
MongoDB | Blog
MongoDB | Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog

CSS Articles by Temani Afif

Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks Let’s Play With Gap Decorations! How to Control Infinite CSS Animations (Part 2 of 2) How to Control Infinite CSS Animations (Part 1 of 2) Two Circles, One Arrow, and Anchor Positioning Making a Responsive Pyramidal Grid With Modern CSS | CSS-Tricks How to Create a CSS-only Elastic Text Effect Making Complex CSS Shapes Using shape() | CSS-Tricks Responsive Hexagon Grid Using Modern CSS | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 2) | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 1) | CSS-Tricks Perfectly Pointed Tooltips: To The Corners Perfectly Pointed Tooltips: All Four Sides Perfectly Pointed Tooltips: A Foundation Sequential linear() Animation With N Elements | CSS-Tricks Infinite Marquee Animation using Modern CSS Better CSS Shapes Using shape() — Part 4: Close and Move | CSS-Tricks Drawing CSS Shapes using corner-shape Better CSS Shapes Using shape() — Part 3: Curves | CSS-Tricks Better CSS Shapes Using shape() — Part 2: More on Arcs | CSS-Tricks Better CSS Shapes Using shape() — Part 1: Lines and Arcs | CSS-Tricks Creating Blob Shapes using clip-path: shape() Creating Flower Shapes using clip-path: shape() Custom progress element using the attr() function A CSS-Only Star Rating Component and More! (Part 2) | CSS-Tricks A CSS-Only Star Rating Component and More! (Part 1) | CSS-Tricks How to Create Wavy Boxes Using CSS Full-Bleed Layout with Modern CSS Fancy Menu Navigation Using Anchor Positioning | CSS-Tricks How to Create a Zig-Zag Box Using CSS How to Create Zig-Zag CSS Loaders Using One Element Custom Progress Element Using Anchor Positioning & Scroll-Driven Animations How to Create Filling CSS Loaders Using One Element How to Create Curved-Edge and Rounded-Edge Shapes Using CSS CSS Tricks That Use Only One Gradient | CSS-Tricks How to create Shapes with Inner Curves using CSS Mask Custom Range Slider Using Anchor Positioning & Scroll-Driven Animations How to Get the Width/Height of Any Element in Only CSS How Keyboard Navigation Works in a CSS Game How To Create Cut-Out Shapes using The clip-path property The Modern Guide For Making CSS Shapes — Smashing Magazine css-shape.com: The Ultimate Collection of CSS-only Shapes ⚡️ Sliding 3D Image Frames In CSS — Smashing Magazine CSS Tricks To Master The clip-path Property Creating Wavy Circles with Fancy Animations in CSS Modern CSS Tooltips And Speech Bubbles (Part 2) — Smashing Magazine Do you need a Tooltip or a Speech Bubble? I have created 100 using CSS 😲 Modern CSS Tooltips And Speech Bubbles (Part 1) — Smashing Magazine Creating Flower Shapes using CSS Mask & Trigonometric Functions CSS Shapes: The Triangle The Complex But Awesome CSS border-image Property — Smashing Magazine CSS Tricks to add 3D Effects to your Text CSS Responsive Multi-Line Ribbon Shapes (Part 2) — Smashing Magazine CSS Responsive Multi-Line Ribbon Shapes (Part 1) — Smashing Magazine I have made 100+ CSS-only Ribbon Shapes | The Perfect Collection 🎀 How to create a CSS-only infinite scroll animation Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 2) — Smashing Magazine Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 1) — Smashing Magazine How to Create CSS Ribbon Shapes with a Single Element CSS Shapes: The Ribbon Revealing Images With CSS Mask Animations — Smashing Magazine css-loaders.com: The Biggest Collection of Loading Animations (more than 500 🤯) How To Define An Array Of Colors With CSS — Smashing Magazine CSS effects on images II Shines, Perspective, And Rotations: Fancy CSS 3D Effects For Images — Smashing Magazine What's your Lucky CSS Pattern? Check It Now! How to Add a CSS Reveal Animation to Your Images Modern Layouts using CSS Grid I created 100+ unique CSS patterns | The best collection 🤩 How to Create a Custom Range Slider Using CSS CSS Shapes: The Heart CSS Shapes: Polygon & Starburst A Text Reveal Animation using CSS CSS Tip: learn CSS the easy way! How to build a CSS-only accordion How to create Breadcrumb Navigation with CSS Different Ways to Get CSS Gradient Shadows | CSS-Tricks A CSS-only responsive Stepper component A Fancy Hover Effect For Your Avatar | CSS-Tricks How to make a zoom effect using CSS Creating a Custom Cursor using CSS CSS Infinite 3D Sliders | CSS-Tricks CSS Infinite Slider Flipping Through Polaroid Images | CSS-Tricks How to create a responsive sidebar menu using CSS CSS Infinite and Circular Rotating Image Slider | CSS-Tricks Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks CSS Grid and Custom Shapes, Part 3 | CSS-Tricks Fancy Image Decorations: Outlines and Complex Animations | CSS-Tricks Fancy Image Decorations: Masks and Advanced Hover Effects | CSS-Tricks Fancy Image Decorations: Single Element Magic | CSS-Tricks How to create an infinite image slider using CSS How to Create Wavy Shapes & Patterns in CSS | CSS-Tricks How I Made a Pure CSS Puzzle Game | CSS-Tricks How to create a Tooltip/Speech Bubble using CSS CSS Grid and Custom Shapes, Part 2 | CSS-Tricks CSS Grid and Custom Shapes, Part 1 | CSS-Tricks Zooming Images in a Grid Layout | CSS-Tricks How to create a CSS-only loader with one element Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers | CSS-Tricks How to create background pattern using CSS & conic-gradient
How to create a responsive hamburger menu using CSS
2022-05-12 · via CSS Articles by Temani Afif

How to create a responsive hamburger menu using CSS

Written on by Temani AfifWeb Developer

Estimated read time 5 minutes

The hamburger menu is a must when dealing with responsive design. Having the ability to show/hide the menu on small screens is essential to keep the navigation on the website easy. In this post, we will build a CSS-only responsive menu with a minimalist code.

This article will be a step-by-step tutorial where we will start by creating the icons until we reach a fully functional menu.

Creating the icons

To build the hamburger menu, we need two icons: The hamburger icon and the close icon. A lot of techniques exist to create such icons and many of them rely on a lot of code but here we are going to use only CSS applied to one HTML element.

For the hamburger menu, we need 3 CSS declarations as follows:

.menu {
  width: 150px; /* control the size */
  aspect-ratio: 1;
  background: linear-gradient(#000 50%, #0000 0) 0 0/100% 40%;
}

We define a square element thanks to width and aspect-ratio then using a gradient we create the 3 bars. Below is an illustration to understand how the gradient is working:

Illustration of the hamburger icon

And the code for the close icon is as follows:

.close {
  width: 150px; /* size of the icon */
  aspect-ratio: 1;
  background: 
    conic-gradient(from 90deg at 33% 33%, #0000 90deg, #000 0) 
    100% 100%/60% 60%;
  transform: translateZ(0px) rotate(45deg);
}

We are using a similar code to the hamburger icon with one value to control the size and a gradient to create the shape. Below is an illustration of the gradient before we apply the rotation:

Illustration of the close icon

The above codes are the simple version of both icons. We can also have the version with rounded edges. For this I will consider more gradients.

For the hamburger icon:

.menu {
  width: 150px; /* update this to control the size */
  aspect-ratio: 1;
  background:
   radial-gradient(closest-side at 12.5% 25%,#000 96%,#0000) 0 0/80% 40%,
   linear-gradient(#000 50%,#0000 0) top/80% 40% repeat-y;
}

Illustration of rounded hamburger icon

And for the close icon:

.close {
  --s: 150px; /* size */
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s)*.1);
  box-sizing: border-box;
  --_g: radial-gradient(farthest-side,#000 96%,#0000);
  background: 
    radial-gradient(closest-side at 50% 12.5%,#000 96%,#0000) top /20% 80% repeat-y,
    radial-gradient(closest-side at 12.5% 50%,#000 96%,#0000) left/80% 20% repeat-x,
    conic-gradient(from 90deg at 33% 33%, #0000 90deg, #000 0) 
     100% 100%/60% 60% padding-box content-box;
  transform: translateZ(0) rotate(45deg);
}

This one is a bit tricky. First, I am considering a CSS variable to define the size as I need to set padding that is equal to 10% of that size. That padding area will allow me to cut the conic-gradient() to leave spaces for the rounded edge. To do this I am using padding-box content-box which set the background-origin to padding-box and the background-clip to content-box

In other words, I am using the padding area to define my gradient then the gradient will show only inside the content area.

Illustration of the background-clip property

Then we add two radial-gradient() for the rounded edges. Both gradients have similar a configuration. I am simply inverting some values.

Illustration of the rounded close icon

Here is a live demo with all the icons together

40%

💰 40% OFF YOUR FIRST MONTH WITH VERPEX MANAGED CLOUD SERVERS

with the discount code

SERVERS-SALE

Creating the button

Now that we have our icons, it’s time to create the menu button that will toggle the visibility of the menu on a small screen. For this task, we are going to rely on a checkbox which is a native toggle that allows us to have two states (checked, unchecked)

In the above demo, I applied the style of the icons to an <input> element. The hamburger icon on the default state (the unchecked) and the close icon on the checked state. As simple as that!

I am also adding extra lines to disable the default styles of the input (you can refer to my previous article for more detail about this part)

input {
  width: 150px; /* control the size */
  aspect-ratio: 1;
  background: linear-gradient(#000 50%, #0000 0) 0 0/100% 40%;
 
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
  cursor:pointer;
}
input:checked {
  background: 
    conic-gradient(from 90deg at 33% 33%, #0000 90deg, #000 0) 
    100% 100%/60% 60%;
  transform: translateZ(0px) rotate(45deg);
}

We can do the same with the rounded version of the icons.

The above demos are the most basic example of a menu button. We are simply toggling between two icons which is enough but we can go further and add some animation.

We can rely on pseudo-elements to create a fading effect:

Each pseudo-element will define one icon then we simply adjust the opacity. The code looks like the below:

input {
  width: 150px;
  aspect-ratio: 1;
  display: grid; /* we define a grid */
}
input:before,
input:after {
  content: "";
  grid-area: 1/1; /* both pseudo element on the top of each other */
  transition: .3s; /* we need some transition */
}
input:before {
  /* put the code for the hamburger icon */
  opacity: 1;
}
input:after {
  /* put the code for the close icon */
  opacity: 0;
}
input:checked:before {
  opacity: 0;
}
input:checked:after {
  opacity: 1;
}

I think the above code is self-explanatory. The same code structure can be used to create more animation.

We can have a scaling effect:

Another idea with a translation effect:

In addition to the static icons, we can consider more fancy animations. We can transform the hamburger icon into the close icon using a lot of techniques while keeping the same HTML code (only the <input> tag).

I won’t get into a lot of details for this part but here are a few examples I recently made:

Now that we have made our button with its animation, it’s time to build the whole menu. The main code will look as follow:

<nav>
  <input type="checkbox" role="button" aria-label="Display the menu" aria-expanded="false" aria-controls="menu">
  <ul id="menu">
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/shop">Shop</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

We create a <nav> element and inside we add the <input> and the menu using <ul>. You will notice the aria-* attributes and the role attribute as well. Those are needed to keep our menu system accessible. I won't detail that part since it’s out of the scope of this article but it’s always good to consider accessibility when writing HTML code (https://web.dev/semantics-aria/)

For the CSS, we will have two parts. In the first part, we will use a media query to have two styles for our menu: one for big screens and one for the mobile menu.

For simplicity, I am going to consider a basic configuration to illustrate the technique:

See the Pen by Temani Afif () on .

If you resize the above demo you will notice that the menu will disappear on small screens (under 600px width as defined by the media query) and the menu button will appear.

Now, we will consider the checked state of the input to toggle the visibility of the menu. For this, we will rely on the sibling selector +. The code will be as follow:

input:checked + ul {
  /* show the menu */
}

Now our menu is fully functional. On big screens, we have a standard menu and on small screens, we have the hamburger menu that we can toggle using a button.

We can still go further and add more styling to our menu and consider a few animations to make the menu appear/disappear nicely but the main trick will always remain the same.

Here is an example where we consider a sliding effect by using transform/opacity instead of display

We can have a lot of animation/effects. The main idea is to define a “hidden” state and a “visible” state that we control using the :checked pseudo-class

50%

SAVE UP TO 50% ON VERPEX YEARLY RESELLER HOSTING PLANS

with the discount code

AWESOME

AWESOME

Wrapping Up

From creating the icons to building the menu, we saw how to create, using CSS and a minimal HTML code, a fully functional responsive menu. Before we end, here is a sum-up of the whole code we used. I am gonna highlight only the important parts.

The HTML code:

<nav>
  <input type="checkbox" role="button" aria-label="Display the menu" aria-expanded="false" aria-controls="menu">
  <ul id="menu">
    <li><a href="..">Menu Item 1</a></li>
    <li><a href="..">Menu Item 2</a></li>
    <!-- ...  -->
  </ul>
</nav>

The CSS code:

/* the CSS code to style the menu for big screens */
nav { ... }
nav ul { ... }
nav ul li a { ... }
nav ul li a:hover { ... }
/**/
nav input {
  /* the CSS style for the hamburger icon */
  display: none; /* hide the input on big screen */
  -webkit-appearance:none;
  -moz-appearance:none;
  appearance:none;
  cursor:pointer;
}
nav input:checked {
  /* the CSS style for the close icon */
}
@media (max-width:600px) { /* update the max-width as you want */
  /* the CSS code to style the menu for mobile screen */
  nav { ... }
  nav ul { 
   display: none; /* hide the menu on mobile */
 }
  nav ul li a { ... }
  nav ul li a:hover { ... }
  /**/
  nav input {
    display: block; /* show the icons on mobile */
  }
  /* show the menu on checked */
  nav input:checked + ul { 
    display: block; 
 }
}

The above code is a kind of “pseudo-code” to highlight the main ideas we used in this article. In a real example, you may need to use a slightly different code like in the last example where I used transform / opacity instead of display to toggle the visibility.

If you want to ensure your site is running optimally, now’s the time to consider speed-optimized web hosting. At Verpex we offer web hosting plans suitable for businesses of any scale.

Frequently Asked Questions

Temani Afif

Temani Afif is an expert web developer, a content creator, and a CSS addict. He is the mastermind behind CSS Loaders, CSS Generators, CSS Tip and many other CSS-related websites.

View more posts by Temani Afif