【CSS】レスポンシブ対応したハンバーガーメニューをCSSのみで作る

■ はじめに

レスポンシブ対応したハンバーガーメニューを作ろうと
ネットで漁ったけど、ほとんどが jQuery を使ったものだった。
今回は、jQuery を使わずに、CSSのみで作ったものを調べてみた。

目次

【1】ハンバーガーメニュー(Hamburger menu)
【2】サンプル

【1】ハンバーガーメニュー(Hamburger menu)

* 三本線のアイコン「≡」で表されるナビゲーションメニューのこと
* 見た目がハンバーガーに似ていることから、この名前が付けられた

【2】サンプル

例1

<!-- HTMLコード -->
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<title>Demo</title>
<style type="text/css">
body {
  margin: 0;
  font-family: Helvetica, sans-serif;
  background-color: #f4f4f4;
}

a {
  color: #000;
}

/* header */

.header {
  background-color: #fff;
  box-shadow: 1px 1px 4px 0 rgba(0,0,0,.1);
  position: fixed;
  width: 100%;
  z-index: 3;
}

.header ul {
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: hidden;
  background-color: #fff;
}

.header li a {
  display: block;
  padding: 20px 20px;
  border-right: 1px solid #f4f4f4;
  text-decoration: none;
}

.header li a:hover,
.header .menu-btn:hover {
  background-color: #f4f4f4;
}

.header .logo {
  display: block;
  float: left;
  font-size: 2em;
  padding: 10px 20px;
  text-decoration: none;
}

/* menu */

.header .menu {
  clear: both;
  max-height: 0;
  transition: max-height .2s ease-out;
}

/* menu icon */

.header .menu-icon {
  cursor: pointer;
  display: inline-block;
  float: right;
  padding: 28px 20px;
  position: relative;
  user-select: none;
}

.header .menu-icon .navicon {
  background: #333;
  display: block;
  height: 2px;
  position: relative;
  transition: background .2s ease-out;
  width: 18px;
}

.header .menu-icon .navicon:before,
.header .menu-icon .navicon:after {
  background: #333;
  content: '';
  display: block;
  height: 100%;
  position: absolute;
  transition: all .2s ease-out;
  width: 100%;
}

.header .menu-icon .navicon:before {
  top: 5px;
}

.header .menu-icon .navicon:after {
  top: -5px;
}

/* menu btn */

.header .menu-btn {
  display: none;
}

.header .menu-btn:checked ~ .menu {
  max-height: 240px;
}

.header .menu-btn:checked ~ .menu-icon .navicon {
  background: transparent;
}

.header .menu-btn:checked ~ .menu-icon .navicon:before {
  transform: rotate(-45deg);
}

.header .menu-btn:checked ~ .menu-icon .navicon:after {
  transform: rotate(45deg);
}

.header .menu-btn:checked ~ .menu-icon:not(.steps) .navicon:before,
.header .menu-btn:checked ~ .menu-icon:not(.steps) .navicon:after {
  top: 0;
}

/* 48em = 768px */

@media (min-width: 48em) {
  .header li {
    float: left;
  }
  .header li a {
    padding: 20px 30px;
  }
  .header .menu {
    clear: none;
    float: right;
    max-height: none;
  }
  .header .menu-icon {
    display: none;
  }
}

</style>
</head>
  <body>
<header class="header">
  <a href="" class="logo">CSS Nav</a>
  <input class="menu-btn" type="checkbox" id="menu-btn" />
  <label class="menu-icon" for="menu-btn"><span class="navicon"></span></label>
  <ul class="menu">
    <li><a href="#work">Our Work</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#careers">Careers</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
</header>
</html>

例2

<!-- HTMLコード -->
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<title>Demo</title>
<style type="text/css">
.c-header {
  align-items: center;
  background-color: #eeeeee;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  padding: 1rem 2rem;
  width: 100%;
}

.c-header__logo {
  color: #000;
  min-width: 80px;
  text-decoration: none;
}

.c-header__list {
  box-sizing: border-box;
  display: flex;
  margin: 0;
  padding: 0;
}

.c-header__list-item {
  list-style: none;
  text-decoration: none;
}

.c-header__list-link {
  color: #000;
  display: block;
  margin-right: 20px;
  text-decoration: none;
  padding: 10px 0px;
}

.c-header__list-link:hover {
  filter: opacity(0.6);
}

.c-hamburger-menu {
  position: relative;
}

@media screen and (max-width: 750px) {
  .c-hamburger-menu__list {
    background-color: #eeeeee;
    align-items: flex-start;
    display: flex;
    flex-direction: column;
    left: 0;
    padding: 2rem;
    position: absolute;
    transform: translateX(-100%);
    transition: 0.3s;
    top: 100%;
    width: 100%;
  }

  #hamburger:checked ~ .c-hamburger-menu__list {
    transform: translateX(0%);
    transition: 0.3s;
  }
}

.c-hamburger-menu__input {
  display: none;
}

.c-hamburger-menu__bg {
  background-color: #000;
  cursor: pointer;
  display: none;
  height: 100vh;
  left: 0;
  opacity: 0.4;
  position: absolute;
  top: 0;
  width: 100%;
  z-index: -1;
}

#hamburger:checked ~ .c-hamburger-menu__bg {
  display: block;
}

.c-hamburger-menu__button {
  display: none;
}

@media screen and (max-width: 750px) {
  .c-hamburger-menu__button {
    align-items: center;
    appearance: none;
    background-color: transparent;
    border: none;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 5px;
    height: 32px;
    justify-content: center;
    width: 32px;
  }
}

.c-hamburger-menu__button-mark {
  background-color: #000;
  display: block;
  height: 1px;
  transition: 0.3s;
  width: 20px;
}

@media screen and (max-width: 750px) {
  #hamburger:checked
    ~ .c-hamburger-menu__button
    .c-hamburger-menu__button-mark:nth-of-type(1) {
    transform: translate(2px, 1px) rotate(45deg);
    transform-origin: 0%;
  }
  #hamburger:checked
    ~ .c-hamburger-menu__button
    .c-hamburger-menu__button-mark:nth-of-type(2) {
    opacity: 0;
  }
  #hamburger:checked
    ~ .c-hamburger-menu__button
    .c-hamburger-menu__button-mark:nth-of-type(3) {
    transform: translate(2px, 3px) rotate(-45deg);
    transform-origin: 0%;
  }
}
</style>
</head>
  <body>
<header class="c-header c-hamburger-menu">
  <a href="#" class="c-header__logo">ロゴ</a>
  <input type="checkbox" name="hamburger" id="hamburger" class="c-hamburger-menu__input"/>
  <label for="hamburger" class="c-hamburger-menu__bg"></label>
  <ul class="c-header__list c-hamburger-menu__list">
    <li class="c-header__list-item">
      <a href="#" class="c-header__list-link">About</a>
    </li>
    <li class="c-header__list-item">
      <a href="#" class="c-header__list-link">Service</a>
    </li>
    <li class="c-header__list-item">
      <a href="#" class="c-header__list-link">Company</a>
    </li>
    <li class="c-header__list-item">
      <a href="#" class="c-header__list-link">Recruit</a>
    </li>
    <li class="c-header__list-item">
      <a href="#" class="c-header__list-link">Contact</a>
    </li>
  </ul>
  <label for="hamburger" class="c-hamburger-menu__button">
    <span class="c-hamburger-menu__button-mark"></span>
    <span class="c-hamburger-menu__button-mark"></span>
    <span class="c-hamburger-menu__button-mark"></span>
  </label>
</header>
</html>

参考文献

https://codepen.io/mutedblues/pen/MmPNPG
https://codepen.io/alvarotrigo/pen/MWEJEWG
https://codepen.io/alvarotrigo/pen/XWejzjR
https://blog.to-ko-s.com/css-hamburger-menu/