@@ -8,7 +8,6 @@ description: >-
|
|
8
8
|
tag
|
9
9
|
i18nReady: true
|
10
10
|
---
|
11
|
-
import Badge from '~/components/Badge.astro';
|
12
11
|
import Blanks from '~/components/tutorial/Blanks.astro';
|
13
12
|
import Box from '~/components/tutorial/Box.astro';
|
14
13
|
import Checklist from '~/components/Checklist.astro';
|
@@ -16,75 +16,66 @@ import Option from '~/components/tutorial/Option.astro';
|
|
16
16
|
import PreCheck from '~/components/tutorial/PreCheck.astro';
|
17
17
|
import { Steps } from '@astrojs/starlight/components';
|
18
18
|
|
19
|
-
Let's add a
|
19
|
+
Let's add a button to open and close your navigation menu on mobile screen sizes, requiring some client-side interactivity!
|
20
20
|
|
21
21
|
<PreCheck>
|
22
|
-
- Create a
|
22
|
+
- Create a menu component
|
23
23
|
- Write a `<script>` to allow your site visitors to open and close the navigation menu
|
24
24
|
- Move your JavaScript to its `.js` file
|
25
25
|
</PreCheck>
|
26
26
|
|
27
|
-
## Build a
|
27
|
+
## Build a Menu component
|
28
28
|
|
29
|
-
Create a `<
|
29
|
+
Create a `<Menu />` component to open and close your mobile menu.
|
30
30
|
|
31
31
|
<Steps>
|
32
|
-
1. Create a file named `
|
32
|
+
1. Create a file named `Menu.astro` in `src/components/`
|
33
33
|
|
34
34
|
|
35
|
-
2. Copy the following code into your component.
|
35
|
+
2. Copy the following code into your component. It creates a button that will be used to toggle the visibility of the navigation links on mobile devices. (You will add the new CSS styles to `global.css` later.)
|
36
36
|
|
37
|
-
```astro title="src/components/
|
37
|
+
```astro title="src/components/Menu.astro"
|
38
38
|
---
|
39
39
|
---
|
40
|
-
<div class="hamburger">
|
41
|
-
|
40
|
+
<button aria-expanded="false" aria-controls="main-menu" class="menu">
|
42
|
-
|
41
|
+
Menu
|
43
|
-
<span class="line"></span>
|
44
|
-
</
|
42
|
+
</button>
|
45
43
|
```
|
46
44
|
|
47
|
-
3. Place this new `<
|
45
|
+
3. Place this new `<Menu />` component just before your `<Navigation />` component in `Header.astro`.
|
48
46
|
|
49
47
|
<details>
|
50
48
|
<summary>Show me the code!</summary>
|
51
49
|
|
52
50
|
```astro title="src/components/Header.astro" ins={2,7}
|
53
51
|
---
|
54
|
-
import
|
52
|
+
import Menu from './Menu.astro';
|
55
53
|
import Navigation from './Navigation.astro';
|
56
54
|
---
|
57
55
|
<header>
|
58
56
|
<nav>
|
59
|
-
<
|
57
|
+
<Menu />
|
60
58
|
<Navigation />
|
61
59
|
</nav>
|
62
60
|
</header>
|
63
61
|
```
|
64
62
|
</details>
|
65
63
|
|
66
|
-
4. Add the following styles for your
|
64
|
+
4. Add the following styles for your Menu component, including some responsive styles:
|
67
65
|
|
68
|
-
```css title="src/styles/global.css" ins={2-
|
66
|
+
```css title="src/styles/global.css" ins={2-9, 33-35, 51-53}
|
69
67
|
/* nav styles */
|
70
|
-
.
|
68
|
+
.menu {
|
71
|
-
padding-right: 20px;
|
72
|
-
cursor: pointer;
|
73
|
-
}
|
74
|
-
|
75
|
-
.hamburger .line {
|
76
|
-
display: block;
|
77
|
-
width: 40px;
|
78
|
-
height: 5px;
|
79
|
-
margin-bottom: 10px;
|
80
|
-
background-color: #
|
69
|
+
background-color: #0d0950;
|
70
|
+
border: none;
|
71
|
+
color: #fff;
|
72
|
+
font-size: 1.2rem;
|
73
|
+
font-weight: bold;
|
74
|
+
padding: 5px 10px;
|
81
75
|
}
|
82
76
|
|
83
77
|
.nav-links {
|
84
78
|
width: 100%;
|
85
|
-
top: 5rem;
|
86
|
-
left: 48px;
|
87
|
-
background-color: #ff9776;
|
88
79
|
display: none;
|
89
80
|
margin: 0;
|
90
81
|
}
|
@@ -97,13 +88,15 @@ Create a `<Hamburger />` component to open and close your mobile menu.
|
|
97
88
|
font-size: 1.2rem;
|
98
89
|
font-weight: bold;
|
99
90
|
text-transform: uppercase;
|
91
|
+
color: #0d0950;
|
100
92
|
}
|
101
93
|
|
102
|
-
.nav-links a:hover,
|
94
|
+
.nav-links a:hover,
|
95
|
+
.nav-links a:focus{
|
103
96
|
background-color: #ff9776;
|
104
97
|
}
|
105
98
|
|
106
|
-
.expanded {
|
99
|
+
:has(.menu[aria-expanded="true"]) .nav-links {
|
107
100
|
display: unset;
|
108
101
|
}
|
109
102
|
|
@@ -121,7 +114,7 @@ Create a `<Hamburger />` component to open and close your mobile menu.
|
|
121
114
|
padding: 15px 20px;
|
122
115
|
}
|
123
116
|
|
124
|
-
.
|
117
|
+
.menu {
|
125
118
|
display: none;
|
126
119
|
}
|
127
120
|
}
|
@@ -131,18 +124,21 @@ Create a `<Hamburger />` component to open and close your mobile menu.
|
|
131
124
|
|
132
125
|
## Write your first script tag
|
133
126
|
|
134
|
-
Your header is not yet **interactive** because it can't respond to user input, like clicking on the
|
127
|
+
Your header is not yet **interactive** because it can't respond to user input, like clicking on the menu to show or hide the navigation links.
|
135
128
|
|
136
129
|
Adding a `<script>` tag provides client-side JavaScript to "listen" for a user event and then respond accordingly.
|
137
130
|
|
138
131
|
<Steps>
|
139
132
|
1. Add the following `<script>` tag to `index.astro`, just before the closing `</body>` tag.
|
140
133
|
|
141
|
-
```astro title="src/pages/index.astro" ins={2-
|
134
|
+
```astro title="src/pages/index.astro" ins={2-9}
|
142
135
|
<Footer />
|
143
136
|
<script>
|
137
|
+
const menu = document.querySelector('.menu');
|
138
|
+
|
144
|
-
|
139
|
+
menu.addEventListener('click', () => {
|
145
|
-
|
140
|
+
const isExpanded = menu.getAttribute('aria-expanded') === 'true';
|
141
|
+
menu.setAttribute('aria-expanded', !isExpanded);
|
146
142
|
});
|
147
143
|
</script>
|
148
144
|
</body>
|
@@ -159,26 +155,32 @@ Instead of writing your JavaScript directly on each page, you can move the conte
|
|
159
155
|
1. Create `src/scripts/menu.js` (you will have to create a new `/scripts/` folder) and move your JavaScript into it.
|
160
156
|
|
161
157
|
```js title="src/scripts/menu.js"
|
158
|
+
const menu = document.querySelector('.menu');
|
159
|
+
|
162
|
-
|
160
|
+
menu.addEventListener('click', () => {
|
163
|
-
|
161
|
+
const isExpanded = menu.getAttribute('aria-expanded') === 'true';
|
162
|
+
menu.setAttribute('aria-expanded', !isExpanded);
|
164
163
|
});
|
165
164
|
```
|
166
165
|
|
167
166
|
2. Replace the contents of the `<script>` tag on `index.astro` with the following file import:
|
168
167
|
|
169
|
-
```astro title="src/pages/index.astro" ins={
|
168
|
+
```astro title="src/pages/index.astro" ins={10} del={3-8}
|
170
169
|
<Footer />
|
171
170
|
<script>
|
171
|
+
const menu = document.querySelector('.menu');
|
172
|
+
|
172
|
-
|
173
|
+
menu.addEventListener('click', () => {
|
173
|
-
|
174
|
+
const isExpanded = menu.getAttribute('aria-expanded') === 'true';
|
175
|
+
menu.setAttribute('aria-expanded', !isExpanded);
|
174
176
|
});
|
175
177
|
|
176
178
|
import "../scripts/menu.js";
|
177
179
|
</script>
|
178
180
|
</body>
|
179
181
|
```
|
180
182
|
|
181
|
-
3. Check your browser preview again at a smaller size and verify that the
|
183
|
+
3. Check your browser preview again at a smaller size and verify that the menu still opens and closes your navigation links.
|
182
184
|
|
183
185
|
|
184
186
|
4. Add the same `<script>` with import to your other two pages, `about.astro` and `blog.astro` and verify that you have a responsive, interactive header on each page.
|