Skip to main content

Overview

Astro Portfolio v3 features a dynamic theming system that allows users to switch between three distinct visual themes: Light, Dark, and Retro. The theme preference is persisted in localStorage and respects the user’s system preferences.
The theme switching logic is implemented in ~/workspace/source/src/components/shared/ThemeSwitcher.astro using vanilla JavaScript with Tailwind CSS utility classes.

Available Themes

Light Theme

Clean, bright theme for daytime viewing with high contrast and readability

Dark Theme

Easy on the eyes for low-light environments with reduced eye strain

Retro Theme

Nostalgic sepia-toned theme with a vintage aesthetic

How It Works

Theme Switcher Component

The ThemeSwitcher component displays different icons based on the current theme and allows users to cycle through themes by clicking:
Location: src/components/shared/ThemeSwitcher.astro:1

Theme Logic

The component includes a client-side script that handles theme detection, switching, and persistence:
The theme type ensures type safety when working with themes.

Initialization

The theme system initializes on page load and after view transitions:
The astro:after-swap event ensures the theme switcher works correctly with Astro’s view transitions feature.

Using Themes in Styles

Tailwind CSS Utilities

The project uses Tailwind’s arbitrary variant feature to apply theme-specific styles:

Icon Transitions

The ThemeSwitcher uses transform and scale to smoothly transition between icons:

CSS Variables

Themes can also be implemented using CSS custom properties:
Then use the variables in your components:

Tailwind Configuration

To enable the custom retro: variant, configure Tailwind:
The darkMode: 'class' setting allows Tailwind’s dark: variant to work with class-based theme switching instead of media queries.

Integration in Navbar

The ThemeSwitcher is integrated into the main navigation:
Location: src/components/navs/Navbar.astro:110-113

Implementing Custom Themes

Adding a New Theme

To add a new theme (e.g., “ocean”):

Step 1: Update Type Definition

Step 2: Update Theme Array

Step 3: Add Theme Icon

Step 4: Configure Tailwind Variant

Step 5: Add Theme Styles

Using the New Theme

Advanced Theme Features

Respecting System Preferences

The theme system automatically detects the user’s system preference on first visit:

Preventing Flash of Wrong Theme

To prevent a flash of the wrong theme on page load, add this script to your <head>:
The is:inline directive tells Astro to include this script inline in the HTML, ensuring it runs before the page renders.

Theme-based Images

Show different images for different themes:
Or use CSS:

Accessibility

The theme switcher follows accessibility best practices:
Features:
  • aria-label describes the button’s purpose
  • Visual focus indicators on hover
  • Keyboard accessible (can be activated with Enter/Space)
  • Smooth transitions for reduced motion preference

Respecting Motion Preferences

To respect users who prefer reduced motion:

Best Practices

  1. Provide sufficient contrast - Ensure text is readable in all themes
  2. Test all themes - View all pages in each theme during development
  3. Use semantic names - Name themes by their purpose, not just colors
  4. Persist user choice - Always save the theme preference
  5. Respect system preferences - Use system preference as default
  6. Avoid theme flash - Load theme before page renders
  7. Support keyboard navigation - Make theme switcher keyboard accessible
  8. Add visual feedback - Show which theme is currently active
  9. Consider images - Provide theme-appropriate images when needed
  10. Document color variables - Keep a reference of theme colors

Troubleshooting

Issue: Theme flashes wrong color on page loadSolution: Add an inline script in <head> to apply theme before render:
Issue: Theme doesn’t persist after page transitionsSolution: Ensure you’re listening to astro:after-swap event and re-initializing.Issue: Custom theme variant not working in TailwindSolution: Make sure you’ve added the variant in tailwind.config.js and rebuilt your CSS.Issue: Icons not showing correctlySolution: Check that each icon has the correct combination of scale/rotate classes for all themes.

Components

Learn more about the ThemeSwitcher component

Project Structure

Understand where theme files are located