Saltar al contenido

De vuelta en tierra firme. ¡Lleva tu blog del día a la noche, sin necesidad de island!

Ahora que puedes construir Astro islands para elementos interactivos, no olvides que puedes llegar bastante lejos con solo JavaScript y CSS vanilla.

Vamos a construir un icono clickeable para permitir a tus usuarios alternar entre modo claro u oscuro usando otra etiqueta <script> para interactividad… sin enviar JavaScript de framework al navegador.

Prepárate para…

  • Construye una alternancia de tema interactiva con solo JavaScript y CSS
  • ¡Envía la menor cantidad de JavaScript posible al navegador!

Añade y estiliza un icono de alternancia de tema

Sección titulada “Añade y estiliza un icono de alternancia de tema”
  1. Crea un nuevo archivo en src/components/ThemeIcon.astro y pega el siguiente código en él:

    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>
  2. Importa y añade el componente <ThemeIcon /> a Header.astro para que se muestre en todas las páginas. Envuelve tanto <ThemeIcon /> como <Menu /> dentro de un <div> para agruparlos para estilizar, y añade la etiqueta <style> como se muestra abajo para algunos estilos básicos que mejoren el 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>
  3. Visita la vista previa de tu navegador en http://localhost:4321 para ver el icono ahora en todas tus páginas. Puedes intentar hacer clic en él, pero aún no has escrito un script para hacerlo interactivo.

Elige algunos colores alternativos para usar en modo oscuro.

  1. En global.css, define algunos estilos oscuros. Puedes elegir los tuyos propios, o copiar y pegar:

    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;
    }

Para añadir interactividad a un componente de Astro, puedes usar una etiqueta <script>. Este script puede verificar y establecer el tema actual desde localStorage y alternar el tema cuando se hace clic en el icono.

  1. Añade la siguiente etiqueta <script> en src/components/ThemeIcon.astro después de tu etiqueta <style>:

    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>
  2. Revisa la vista previa de tu navegador en http://localhost:4321 y haz clic en el icono de tema. Verifica que puedes cambiar entre los modos claro y oscuro.

Elige si cada una de las siguientes afirmaciones describe etiquetas <script> de Astro, componentes de framework de UI, o ambos.

  1. Te permiten incluir elementos de UI interactivos en tu sitio web.

  2. Crearán elementos estáticos en tu sitio a menos que incluyas un client: para enviar su JavaScript al cliente y ejecutarlo en el navegador.

  3. Te permiten “probar” un nuevo framework sin requerir que comiences un proyecto completamente nuevo usando esa pila de tecnología.

  4. Te permiten reutilizar código que has escrito en otros frameworks y a menudo puedes simplemente colocarlos directamente en tu sitio.

  5. Te permiten añadir interactividad sin necesidad de conocer o aprender ningún otro framework de JavaScript.

Contribuir Comunidad Patrocinar