Day25 有料的 CSS 漢堡選單
我們今天要來做幾份漢堡選單。
原理和 Day14 今天我想來點… 純 CSS 的開關 一樣,都是用 input
的 checkbox
來儲存狀態好讓其他元素可以抓到。而他本身的狀態使用 label
來遠端遙控。
我先不要一次跳太多步驟。這是一個基本還未完成的版面。
1<input type="checkbox" id="menu" />
2<label for="menu">
3 <div></div>
4 <div></div>
5 <div></div>
6 <span class="cover"></span>
7</label>
1label {
2 width: 3rem;
3 height: 3rem;
4 background: #00c3ff;
5 display: block;
6 border-radius: 50%;
7 display: flex;
8 flex-direction: column;
9 align-items: center;
10 justify-content: center;
11 gap: 0.25em;
12 position: relative;
13}
14
15label div {
16 width: 1.5rem;
17 height: 0.25rem;
18 background: #fff;
19 border-radius: 0.25rem;
20}
21.cover {
22 position: absolute;
23 display: block;
24 top: 50%;
25 left: 50%;
26 transform: translate(-50%, -50%);
27 width: 100vmax;
28 height: 100vmax;
29 border-radius: 50%;
30 background: #80e1ff;
31 z-index: -1;
32}
可以看到我們已經有了漢堡選單的樣子。<label>
使用 flex 來垂直排列並且置中,gap
來設定間距,並設定 position: relative
來讓 position: absolute
的 .cover
可以定位到相同位置。
如果已經看不懂的話可以複習:
藍色圓形我們希望能夠填滿整個畫面,所以我們使用 100vmax
來選擇 vw
和 vh
之間比較大的值,這樣可以確保能夠蓋滿畫面但是長寬還是依樣來保持圓形。你會發現只有蓋住螢幕一半是因為我們把她往左上角移動了一半,所以只有一半的圓形在畫面上。沒關係我們為了安全起見設定大一點。最後使用 z-index
來讓他在最底層。
把原本的勾選框隱藏起來再加上內文。漢堡選單裡面當然就是要放漢堡配料,效果如下
1<input type="checkbox" id="menu" checked />
2<label for="menu">
3 <div></div>
4 <div></div>
5 <div></div>
6 <span class="cover">
7 <ul>
8 <li>麵包</li>
9 <li>肉排</li>
10 <li>青菜</li>
11 <li>麵包</li>
12 </ul>
13 </span>
14</label>
1body {
2 overflow: hidden;
3 font-family: system-ui;
4}
5input[type="checkbox"] {
6 display: none;
7}
8label {
9 width: 3rem;
10 height: 3rem;
11 background: #00c3ff;
12 display: block;
13 border-radius: 50%;
14 display: flex;
15 flex-direction: column;
16 align-items: center;
17 justify-content: center;
18 gap: 0.25em;
19 position: relative;
20 cursor: pointer;
21}
22
23label div {
24 width: 1.5rem;
25 height: 0.25rem;
26 background: #fff;
27 border-radius: 0.25rem;
28 transition: all 0.3s;
29}
30.cover {
31 position: absolute;
32 display: block;
33 top: 50%;
34 left: 50%;
35 transform: translate(-50%, -50%);
36 width: 0;
37 height: 0;
38 border-radius: 50%;
39 background: #80e1ff;
40 z-index: -1;
41 transition: all 0.3s;
42 overflow: hidden;
43}
44input:checked ~ label > .cover {
45 width: 250vmax;
46 height: 250vmax;
47 border-radius: 50%;
48}
49
50ul {
51 position: absolute;
52 top: 50%;
53 left: 50%;
54 width: 100vw;
55 color: #fff;
56 font-size: 3em;
57 list-style: none;
58 font-weight: 700;
59}
最後是漢堡動畫,這裡就要發揮你自己的創意了。原理不難,這裡提供一個我現在想到的做法。我想要最上面的和最下面的旋轉 45 度,中間的變短到消失。所以我們先把中間的設定 width: 0; height: 0;
,然後我們把最上面的和最下面的設定 transform: rotate(45deg);
,這樣就會旋轉 45 度了。這樣能夠做出一個箭頭:
1input:checked ~ label > div:first-child {
2 transform: rotate(-45deg);
3}
4input:checked ~ label > div:nth-child(2) {
5 width: 0;
6}
7input:checked ~ label > div:nth-child(3) {
8 transform: rotate(45deg);
9}
再來做一個也很常見的打叉,為了方便我們乾脆全部使用 absolute 定位。成果如下:
https://codepen.io/edit-mr/pen/zYyyEgz
1body {
2 overflow: hidden;
3 font-family: system-ui;
4}
5input[type="checkbox"] {
6 display: none;
7}
8label {
9 width: 3rem;
10 height: 3rem;
11 background: #00c3ff;
12 display: block;
13 border-radius: 50%;
14 position: relative;
15 cursor: pointer;
16}
17
18label div {
19 position: absolute;
20 width: 1.5rem;
21 height: 0.25rem;
22 background: #fff;
23 border-radius: 0.25rem;
24 transition: all 0.3s;
25 top: 50%;
26 left: 50%;
27 transform: translate(-50%, -50%);
28}
29.cover {
30 position: absolute;
31 display: block;
32 top: 50%;
33 left: 50%;
34 transform: translate(-50%, -50%);
35 width: 0;
36 height: 0;
37 border-radius: 50%;
38 background: #80e1ff;
39 z-index: -1;
40 transition: all 0.3s;
41 overflow: hidden;
42}
43input:checked ~ label > .cover {
44 width: 250vmax;
45 height: 250vmax;
46 border-radius: 50%;
47}
48
49ul {
50 position: absolute;
51 top: 50%;
52 left: 50%;
53 width: 100vw;
54 color: #fff;
55 font-size: 3em;
56 list-style: none;
57 font-weight: 700;
58}
59input:checked ~ label div:first-child {
60 left: 25%;
61 top: 50%;
62 transform: rotate(45deg);
63}
64input:checked ~ label div:nth-child(2) {
65 width: 0;
66}
67input:checked ~ label div:nth-child(3) {
68 left: 25%;
69 top: 50%;
70 transform: rotate(-45deg);
71}
72label > div:first-child {
73 top: calc(50% - 0.5rem);
74}
75label > div:nth-child(3) {
76 top: calc(50% + 0.5rem);
77}
你以為這樣就結束了?還記得我們昨天講的 Day24 CSS 相融黏滯效果 嗎?我們可以把他加上去讓他更有質感。
這是一個會四處噴射漢堡選單
1<input type="checkbox" id="menu" checked />
2<label for="menu">
3 <div>🥩</div>
4 <div>🥬</div>
5 <div>🧀</div>
6 🍔
7</label>
1body {
2 overflow: hidden;
3 font-family: system-ui;
4}
5
6input[type="checkbox"] {
7 display: none;
8}
9
10label {
11 width: 5rem;
12 height: 5rem;
13 background: #00c3ff;
14 display: block;
15 border-radius: 50%;
16 position: relative;
17 cursor: pointer;
18 margin: 1em auto;
19}
20
21div {
22 position: absolute;
23 top: 50%;
24 left: 50%;
25 transform: translate(-50%, -50%);
26 width: 3rem;
27 height: 3rem;
28 border-radius: 50%;
29 background: #00c3ff;
30 z-index: -1;
31 transition: all 0.3s;
32 overflow: hidden;
33}
34
35input:checked ~ label > div:nth-child(1) {
36 left: calc(50% - 5rem);
37}
38
39input:checked ~ label > div:nth-child(2) {
40 top: calc(50% + 5rem);
41}
42input:checked ~ label > div:nth-child(3) {
43 left: calc(50% + 5rem);
44}
45
46label,
47div {
48 display: flex;
49 align-items: center;
50 justify-content: center;
51 font-size: 2.5rem;
52 user-select: none;
53}
54
55div {
56 font-size: 1.5rem;
57}
user-select: none;
可以讓使用者無法選取文字,這樣就不會在點擊時有文字被選取的問題了。
加上昨天的相黏效果,變得更可愛了。
https://codepen.io/edit-mr/pen/NWeeYRq
1body {
2 overflow: hidden;
3 font-family: system-ui;
4 min-height: 100svh;
5}
6input[type="checkbox"] {
7 display: none;
8}
9label {
10 width: 5rem;
11 height: 5rem;
12 display: block;
13 position: absolute;
14 cursor: pointer;
15 left: 50%;
16 transform: translate(-50%, -50%);
17}
18.box div {
19 width: 4rem;
20 height: 4rem;
21}
22.box div,
23label {
24 top: 50%;
25 border-radius: 50%;
26 background: #00c3ff;
27}
28.box div,
29.food,
30.food div {
31 position: absolute;
32 left: 50%;
33 transform: translate(-50%, -50%);
34 transition: 0.3s;
35}
36input:checked ~ .box div:first-child,
37input:checked ~ .food div:first-child {
38 left: calc(50% - 4rem);
39}
40input:checked ~ .box div:nth-child(2),
41input:checked ~ .food div:nth-child(2) {
42 top: calc(50% + 4rem);
43}
44input:checked ~ .box div:nth-child(3),
45input:checked ~ .food div:nth-child(3) {
46 left: calc(50% + 4rem);
47}
48.box div,
49label {
50 user-select: none;
51 filter: blur(10px);
52}
53.box {
54 background: #fff;
55 filter: contrast(20) hue-rotate(45deg);
56 height: 100svh;
57}
58.food,
59.food div {
60 top: 50.3%;
61 user-select: none;
62 pointer-events: none;
63}
64input:checked ~ .food div {
65 font-size: 1.5rem;
66}
67.food div {
68 font-size: 0rem;
69}
70.food div:last-child {
71 font-size: 2rem;
72}
手機版的淘寶之前有使用過類似的效果製作分享選單喔~
因為相黏效果有先模糊,裡面的 Emoji 文字也會被模糊,所以我們在後面又做一個只有文字的 .food
來顯示文字。設定 pointer-events: none
就可以讓他不會被點擊到了,直接穿透去點擊下面的 label
。
背景顏色一定要記得設定,不然只會糊再一起沒有相黏效果。這是我 debug 半小時之後才想到的...
以上就是我今天的分享,歡迎在 Instagram 和 Google 新聞追蹤毛哥EM資訊密技,也歡迎訂閱我新開的YouTube 頻道:網棧。
我是毛哥EM,讓我們明天再見。