Back on dry land. Take your blog from day to night, no island required!
هذا المحتوى غير متوفر بلغتك بعد.
Now that you can build Astro islands for interactive elements, don’t forget that you can go pretty far with just vanilla JavaScript and CSS!
Let’s build a clickable icon to let your users toggle between light or dark mode using another <script>
tag for interactivity… with no framework JavaScript sent to the browser.
استعد لـ…
- Build an interactive theme toggle with only JavaScript and CSS
- Send as little JavaScript to the browser as possible!
Add and style a theme toggle icon
Section titled “Add and style a theme toggle icon”-
Create a new file at
src/components/ThemeIcon.astro
and paste the following code into it:src/components/ThemeIcon.astro ------<button id="themeToggle" aria-label="Toggle theme"><svg aria-hidden="true" width="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path class="sun" fill-rule="evenodd" d="M12 17.5a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm0 1.5a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm12-7a.8.8 0 0 1-.8.8h-2.4a.8.8 0 0 1 0-1.6h2.4a.8.8 0 0 1 .8.8zM4 12a.8.8 0 0 1-.8.8H.8a.8.8 0 0 1 0-1.6h2.5a.8.8 0 0 1 .8.8zm16.5-8.5a.8.8 0 0 1 0 1l-1.8 1.8a.8.8 0 0 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM6.3 17.7a.8.8 0 0 1 0 1l-1.7 1.8a.8.8 0 1 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM12 0a.8.8 0 0 1 .8.8v2.5a.8.8 0 0 1-1.6 0V.8A.8.8 0 0 1 12 0zm0 20a.8.8 0 0 1 .8.8v2.4a.8.8 0 0 1-1.6 0v-2.4a.8.8 0 0 1 .8-.8zM3.5 3.5a.8.8 0 0 1 1 0l1.8 1.8a.8.8 0 1 1-1 1L3.5 4.6a.8.8 0 0 1 0-1zm14.2 14.2a.8.8 0 0 1 1 0l1.8 1.7a.8.8 0 0 1-1 1l-1.8-1.7a.8.8 0 0 1 0-1z"/><path class="moon" fill-rule="evenodd" d="M16.5 6A10.5 10.5 0 0 1 4.7 16.4 8.5 8.5 0 1 0 16.4 4.7l.1 1.3zm-1.7-2a9 9 0 0 1 .2 2 9 9 0 0 1-11 8.8 9.4 9.4 0 0 1-.8-.3c-.4 0-.8.3-.7.7a10 10 0 0 0 .3.8 10 10 0 0 0 9.2 6 10 10 0 0 0 4-19.2 9.7 9.7 0 0 0-.9-.3c-.3-.1-.7.3-.6.7a9 9 0 0 1 .3.8z"/></svg></button><style>#themeToggle {border: 0;background: none;}.sun { fill: black; }.moon { fill: transparent; }:global(.dark) .sun { fill: transparent; }:global(.dark) .moon { fill: white; }</style> -
Import and add the
<ThemeIcon />
component toHeader.astro
so that it will be displayed on all pages. Wrap both<ThemeIcon />
and<Menu />
inside a<div>
to group them together for styling, and add the<style>
tag as shown below for some basic styles to improve the layout.src/components/Header.astro ---import Menu from './Menu.astro';import Navigation from './Navigation.astro';import ThemeIcon from './ThemeIcon.astro';---<header><nav><div><ThemeIcon /><Menu /></div><Navigation /></nav></header><style>div {display: flex;justify-content: space-between;}</style> -
Visit your browser preview at
http://localhost:4321
to see the icon now on all your pages. You can try clicking it, but you have not written a script to make it interactive yet.
Add CSS styling for a dark theme
Section titled “Add CSS styling for a dark theme”Choose some alternate colors to use in dark mode.
-
In
global.css
, define some dark styles. You can choose your own, or copy and paste:src/styles/global.css html.dark {background-color: #0d0950;color: #fff;}.dark .menu {background-color: #fff;color: #000;}.dark .nav-links a:hover,.dark .nav-links a:focus {color: #0d0950;}.dark .nav-links a {color: #fff;}.dark a {color: #ff9776;}
When you update your site to include dark mode, some colors used may need updating.
Always check your rendered site when adding new styles and colors, and make adjustments when necessary! This can mean adding more .dark
CSS style rules to display different styles in dark mode, or you may wish to update some colors so that they work equally well in both themes.
Consider using accessibility tools such as a contrast checker when creating a set of colors for your site. Or, you can run a check on your website with a browser extension to spot any potential issues.
Add client-side interactivity
Section titled “Add client-side interactivity”To add interactivity to an Astro component, you can use a <script>
tag. This script can check and set the current theme from localStorage
and toggle the theme when the icon is clicked.
-
Add the following
<script>
tag insrc/components/ThemeIcon.astro
after your<style>
tag:src/components/ThemeIcon.astro <style>.sun { fill: black; }.moon { fill: transparent; }:global(.dark) .sun { fill: transparent; }:global(.dark) .moon { fill: white; }</style><script is:inline>const theme = (() => {const localStorageTheme = localStorage?.getItem("theme") ?? '';if (['dark', 'light'].includes(localStorageTheme)) {return localStorageTheme;}if (window.matchMedia('(prefers-color-scheme: dark)').matches) {return 'dark';}return 'light';})();if (theme === 'light') {document.documentElement.classList.remove('dark');} else {document.documentElement.classList.add('dark');}window.localStorage.setItem('theme', theme);const handleToggleClick = () => {const element = document.documentElement;element.classList.toggle("dark");const isDark = element.classList.contains("dark");localStorage.setItem("theme", isDark ? "dark" : "light");}document.getElementById("themeToggle")?.addEventListener("click", handleToggleClick);</script> -
Check your browser preview at
http://localhost:4321
and click the theme icon. Verify that you can change between light and dark modes.
Test your knowledge
Section titled “Test your knowledge”Choose whether each of the following statements describes Astro <script>
tags, UI framework components, or both.
-
They allow you to include interactive UI elements on your website.
-
They will create static elements on your site unless you include a
client:
to send their JavaScript to the client and run in the browser. -
They allow you to “try out” a new framework without requiring you to start an entirely new project using that tech stack.
-
They allow you to reuse code you have written in other frameworks and you can often just drop them right into your site.
-
They allow you to add interactivity without needing to know or learn any other JavaScript frameworks.