こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
<目次>
実装するもの
今回は、回転するメニューバーをCSSで実装します。
demoは、「こちら」で確認できます。
環境構築
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
JavaScript版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" /> <link rel="stylesheet" href="style.css" /> <title>Rotating Navigation</title> </head> <body> <div class="container"> <div class="circle-container"> <div class="circle"> <button id="close"> <i class="fas fa-times"></i> </button> <button id="open"> <i class="fas fa-bars"></i> </button> </div> </div> <div class="content"> <h1>Amazing Article</h1> <small>Florin Pop</small> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quia in ratione dolores cupiditate, maxime aliquid impedit dolorem nam dolor omnis atque fuga labore modi veritatis porro laborum minus, illo, maiores recusandae cumque ipsa quos. Tenetur, consequuntur mollitia labore pariatur sunt quia harum aut. Eum maxime dolorem provident natus veritatis molestiae cumque quod voluptates ab non, tempore cupiditate? Voluptatem, molestias culpa. Corrupti, laudantium iure aliquam rerum sint nam quas dolor dignissimos in error placeat quae temporibus minus optio eum soluta cupiditate! Cupiditate saepe voluptates laudantium. Ducimus consequuntur perferendis consequatur nobis exercitationem molestias fugiat commodi omnis. Asperiores quia tenetur nemo ipsa.</p> <h3>My Dog</h3> <img src="https://images.unsplash.com/photo-1507146426996-ef05306b995a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80" alt="doggy" /> <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sit libero deleniti rerum quo, incidunt vel consequatur culpa ullam. Magnam facere earum unde harum. Ea culpa veritatis magnam at aliquid. Perferendis totam placeat molestias illo laudantium? Minus id minima doloribus dolorum fugit deserunt qui vero voluptas, ut quia cum amet temporibus veniam ad ea ab perspiciatis, enim accusamus asperiores explicabo provident. Voluptates sint, neque fuga cum illum, tempore autem maxime similique laborum odio, magnam esse. Aperiam?</p> </div> </div> <nav> <ul> <li><i class="fas fa-home"></i> Home</li> <li><i class="fas fa-user-alt"></i> About</li> <li><i class="fas fa-envelope"></i> Contact</li> </ul> </nav> <script src="script.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 要素の取得 // openボタン const open = document.getElementById('open') // closeボタン const close = document.getElementById('close') // コンテナ const container = document.querySelector('.container') // openのクリックイベント登録 open.addEventListener('click', () => container.classList.add('show-nav')) // closeのクリックイベント登録 close.addEventListener('click', () => container.classList.remove('show-nav')) |
現状では、以下のように表示されます。

スタイリング
これからスタイリングを実装します。
項目にbodyなどが出てきますが、これはHTMLの要素です。
全体設定
ページ全体のスタイリングをします。
1 2 3 4 5 6 7 8 9 |
/* フォント */ @import url("https://fonts.googleapis.com/css?family=Lato&display=swap"); * { /* ボックス要素のサイズを算出 パディング(padding)とボーダー(border)を 幅(width)と高さ(height)に含める */ box-sizing: border-box; } |
body
bodyのスタイリングをします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* 変数を定義 */ :root { --bgcolor: #333; --basefontcolor: #222; } body { /* フォント指定 */ font-family: "Lato", sans-serif; /* 背景色 */ background-color: var(--bgcolor); /* フォント色 */ color: var(--basefontcolor); /* x軸方向の要素のはみ出を隠す これによりページのX軸方向のスライダーが 表示されなくなる */ overflow-x: hidden; } |

container
次は、containerのスタイリングします。
1 2 3 4 5 6 7 8 9 10 11 12 |
.container { /* 背景色 */ background-color: #fafafa; /* 要素の変形transformにおける原点を設定 */ transform-origin: top left; /* アニメーション設定 */ transition: transform 0.5s linear; /* vhはビューポート(画面サイズ)に対しての割合*/ width: 100vh; min-height: 100vh; padding: 50px; } |

container.show-nav
show-navは、JavaScriptで動的に付与するクラスです。
1 2 3 4 |
.container.show-nav { /* コンテナ要素の傾き指定 */ transform: rotate(-20deg); } |

circle
circleのスタイリングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.circle { /* 背景色 */ background-color: #ff7979; /* 高さ */ height: 200px; /* 幅 */ width: 200px; /* 輪郭を丸く */ border-radius: 50%; /* 子要素に対して基準位置にする */ position: relative; /* アニメーション設定 */ transition: transform 0.5s linear; } |

circle-container
circle-containerのスタイリングします。
1 2 3 4 5 6 |
.circle-container { /* 位置を固定 */ position: fixed; top: -100px; left: -100px; } |

circle button
circle buttonのスタイリングをします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
.circle button { /* カーソルを指定 */ cursor: pointer; /* 親要素(relative)からの位置指定 */ position: absolute; /* ページ上部からの位置 */ top: 50%; /* ページ左部からの位置 */ left: 50%; /* 高さ */ height: 100px; /* 背景色は親要素を継承 */ background: transparent; /* 枠なし */ border: 0; font-size: 26px; color: #fff; } /* ボタンを押した時のスタイリング */ .circle button:focus { /* 枠線が青くなる挙動をリセット */ outline: none; } .circle button#open { /* ページ左部からの位置 */ left: 60%; } |

circle button#close
circle button#closeのスタイリングをします。
1 2 3 4 5 6 7 8 |
.circle button#close { /* ページ上部からの位置 */ top: 60%; /* circleの傾きを指定 */ transform: rotate(90deg); /* 要素の変形transformにおける原点を設定 */ transform-origin: top left; } |

container.show-nav .circle
container.show-nav .circleのスタイリングをします。
1 2 3 4 |
.container.show-nav .circle { /* circleの傾きを指定 */ transform: rotate(-70deg); } |
この時点で、以下のように動きます。
nav
navのスタイリングをします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
nav { position: fixed; bottom: 40px; left: 0; z-index: 100; } nav ul { /* リスト項目要素のマーカーを設定 ここでは、点を無くす */ list-style-type: none; } nav ul li { /* テキスト全てを大文字 */ text-transform: uppercase; color: #fff; margin: 40px 0; /* x軸方向に移動 */ transform: translateX(-100%); transition: transform 0.4x ease-in; } nav ul li i { font-size: 20px; margin-right: 10px; } nav ul li + li { margin-left: 15px; transform: translateX(-150%); } nav ul li + li + li { margin-left: 30px; transform: translateX(-200%); } |

container.show-nav + nav li
container.show-nav + nav liのスタイリングをします。
1 2 3 4 |
.container.show-nav + nav li { transform: translateX(0); transition-delay: 0.3s; } |

content
contentのスタイリングをします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
.content img { max-width: 100%; } .content { max-width: 1000px; margin: 50px auto; } .content h1 { margin: 0; } .content small { color: #555; font-style: italic; } .content p { color: #333; line-height: 1.5; } |

これで完成といきたいところですが、ページの横幅がおかしいので、修正します。
1 2 3 4 5 6 |
.container { ... /* ビューポート(画面サイズ)に対しての割合*/ width: 100vw; /*vh -> vwに変更*/ ... } |

これで、OKですね。
おわりに
CSSは難しいですね^^;
一つ一つのプロパティがわかっても、それをどう組み合わせれば必要とするスタイルになるのかよく検討して実装しなければなりません。
そもそも、デザインすら思いつきませんけどねw
腕をあげるには、実際に自分で作ることが大切ですよね。特にtransitionを使ったアニメーション制御をよく勉強しておくといいと思います。
それでは、また!
CSSまとめ
CSSソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
/* フォント */ @import url("https://fonts.googleapis.com/css?family=Lato&display=swap"); * { /* ボックス要素のサイズを算出 パディング(padding)とボーダー(border)を 幅(width)と高さ(height)に含める */ box-sizing: border-box; } /* 変数を定義 */ :root { --bgcolor: #333; --basefontcolor: #222; } body { /* フォント指定 */ font-family: "Lato", sans-serif; /* 背景色 */ background-color: var(--bgcolor); /* フォント色 */ color: var(--basefontcolor); /* x軸方向の要素のはみ出を隠す これによりページのX軸方向のスライダーが 表示されなくなる */ overflow-x: hidden; } .container { /* 背景色 */ background-color: #fafafa; /* 要素の変形transformにおける原点を設定 */ transform-origin: top left; /* アニメーション設定 */ transition: transform 0.5s linear; /* ビューポート(画面サイズ)に対しての割合*/ width: 100vw; min-height: 100vh; padding: 50px; } .container.show-nav { /* コンテナ要素の傾き指定 */ transform: rotate(-20deg); } .circle-container { /* 位置を固定 */ position: fixed; /* ページトップからの位置 */ top: -100px; /* ページ左部からの位置 */ left: -100px; } .circle { /* 背景色 */ background-color: #ff7979; /* 高さ */ height: 200px; /* 幅 */ width: 200px; /* 輪郭を丸く */ border-radius: 50%; /* 子要素に対して基準位置にする */ position: relative; /* アニメーション設定 */ transition: transform 0.5s linear; } .container.show-nav .circle { /* circleの傾きを指定 */ transform: rotate(-70deg); } .circle button { /* カーソルを指定 */ cursor: pointer; /* 親要素(relative)からの位置指定 */ position: absolute; /* ページ上部からの位置 */ top: 50%; /* ページ左部からの位置 */ left: 50%; /* 高さ */ height: 100px; /* 背景色は親要素を継承 */ background: transparent; /* 枠なし */ border: 0; font-size: 26px; color: #fff; } /* ボタンを押した時のスタイリング */ .circle button:focus { /* 枠線が青くなる挙動をリセット */ outline: none; } .circle button#open { /* ページ左部からの位置 */ left: 60%; } .circle button#close { /* ページ上部からの位置 */ top: 60%; /* circleの傾きを指定 */ transform: rotate(90deg); /* 要素の変形transformにおける原点を設定 */ transform-origin: top left; } .container.show-nav + nav li { transform: translateX(0); transition-delay: 0.3s; } nav { position: fixed; bottom: 40px; left: 0; z-index: 100; } nav ul { /* リスト項目要素のマーカーを設定 ここでは、点を無くす */ list-style-type: none; } nav ul li { /* テキスト全てを大文字 */ text-transform: uppercase; color: #fff; margin: 40px 0; /* x軸方向に移動 */ transform: translateX(-100%); transition: transform 0.4x ease-in; } nav ul li i { font-size: 20px; margin-right: 10px; } nav ul li + li { margin-left: 15px; transform: translateX(-150%); } nav ul li + li + li { margin-left: 30px; transform: translateX(-200%); } .content img { max-width: 100%; } .content { max-width: 1000px; margin: 50px auto; } .content h1 { margin: 0; } .content small { color: #555; font-style: italic; } .content p { color: #333; line-height: 1.5; } |
コメントを残す
コメントを投稿するにはログインしてください。