Skip to content

๐ŸŽ‰ Shiro v1.2.0 Released: Dark Mode, TOC Sidebar, Reading Progress & Major Refinements

Choose a tag to compare

@Acris Acris released this 08 Mar 04:30
· 220 commits to main since this release
6b377b5

I'm excited to share Shiro v1.2.0 โ€” a major update that brings dark mode, table of contents sidebar, reading enhancements, and extensive code quality improvements to the theme!


โœจ What's New

๐ŸŒ™ Dark Mode

  • Three-state toggle: System โ†’ Light โ†’ Dark, with localStorage persistence
  • "ๅคœใฎ็™ฝ" design: Warm neutral gray tones that complement the light mode's washi paper aesthetic โ€” not a cold inversion, but a moonlit version of the same design language
  • Vermilion accent preserved: The signature seal red remains the visual anchor in both modes
  • FOUC prevention: Inline script in <head> applies the correct theme before first paint โ€” no flash of wrong colors
  • Configurable: dark_mode.default (system/light/dark) and dark_mode.toggle (show/hide the toggle button) in _config.yml

๐Ÿ“‘ Table of Contents Sidebar

  • Auto-generated TOC sidebar for articles with configurable heading depth (toc.depth)
  • Only appears when the article has enough headings (toc.min_headings)
  • Active heading highlighted with a vermilion dot indicator that follows your reading position
  • Sticky "็›ฎๅฝ•" title that stays visible while scrolling through long TOC lists
  • Smooth auto-scroll to keep the active item visible in the TOC panel
  • Heading positions cached for performance; automatically recalculated on resize and image load
  • Configurable via toc.enabled, toc.depth, and toc.min_headings in _config.yml

๐Ÿ“Š Reading Progress Bar

  • Thin vermilion progress bar fixed at the top of the page, updating in real-time as you scroll
  • Automatically hidden on short pages (content less than one viewport height)
  • Respects prefers-reduced-motion
  • Configurable via progress_bar.enabled in _config.yml

โฌ†๏ธ Back to Top Button

  • Elegant circular button that fades in after scrolling past one viewport height
  • Smooth scroll back to top, respects prefers-reduced-motion
  • Configurable via back_to_top.enabled in _config.yml

๐Ÿ–ฅ๏ธ Code Block Enhancements

  • Language labels: Automatically extracted from Hexo's highlight classes and displayed above code blocks
  • Copy button: One-click copy with visual feedback, error handling for non-HTTPS environments
  • Fixed width: Code blocks maintain consistent width regardless of content length
  • Long inline code wrapping: Inline <code> elements wrap gracefully on mobile without breaking layout

๐Ÿ”ง Improvements

Performance

  • Archive page rendering optimized from O(nยฒ) to O(n) single-pass year grouping
  • LightGallery CSS/JS conditionally loaded only on post and page layouts
  • Google Fonts moved from CSS @import (render-blocking) to async <link rel="preload"> with onload fallback
  • All scripts use defer attribute for parallel downloading
  • TOC heading positions cached to avoid scroll-time reflow; resize events debounced
  • theme-transition narrowed from * selector to key elements only
  • Google Analytics moved from <head> to before </body> to avoid render blocking
  • Progress bar hidden on short pages to avoid unnecessary 100% display

Accessibility

  • Theme toggle button updates aria-label dynamically to reflect current state
  • Mobile menu implements focus trap with Tab key cycling
  • Navigation separator / has aria-hidden="true"
  • Decorative elements properly marked with aria-hidden

Security

  • Disqus shortname XSS protection via dump | safe filter
  • Clipboard API error handling with .catch() for non-HTTPS environments
  • IntersectionObserver fallback for unsupported browsers in Disqus lazy loading

Code Quality

  • Dark mode uses 12 semantic CSS variables (--color-text-heading, --color-bg-panel, etc.) โ€” changing the dark palette only requires editing variable definitions
  • Simple utilities (text-footnote, tracking-note, max-h-menu, max-w-divider) migrated to Tailwind v4 @utility syntax
  • Extracted .header-pill-btn component class to eliminate duplicate inline styles
  • Replaced bg-white hack with bg-paper for proper dark mode support
  • All JS files wrapped in IIFE with defer, removed redundant DOMContentLoaded listeners
  • Unified import ... as ui with context across all templates
  • DRY improvements: extracted clean_description variable in head.njk, has_excerpt in post-card.njk
  • Replaced inline SVG in post.njk with icon_chevron_down macro call
  • preconnect hints moved before CSS links for earlier connection
  • Washi paper texture optimized: removed invisible fog layers, fiber angles randomized with coprime background-size to reduce repetition

i18n

  • All 9 language files (default, en, en-US, zh-CN, zh-TW, ja, ja-JP, fr, fr-FR) updated with new feature strings
  • Theme toggle labels: light / dark / system

Documentation

  • README.md rewritten with complete feature list, project structure, development guide, and configuration reference
  • Live demo link added

๐Ÿ› ๏ธ Upgrade Notes

To update your theme, pull the latest changes:

# npm
npm install hexo-theme-shiro@latest

# git
cd themes/shiro
git pull

New configuration options โ€” add the following to your _config.shiro.yml:

# Table of Contents (TOC)
toc:
  enabled: true
  depth: 3
  min_headings: 3

# Dark Mode
dark_mode:
  default: system    # system | light | dark
  toggle: true       # Show toggle button (set to false to disable switching)

# Reading Progress Bar
progress_bar:
  enabled: true

# Back to Top Button
back_to_top:
  enabled: true

If you've customized templates or styles, you may want to review the changes before merging โ€” this release includes significant CSS restructuring for dark mode support.


๐Ÿค Feedback

Thank you for using Shiro! If you encounter any issues with the new features or have suggestions, please feel free to open an issue.

If you enjoy using Shiro, please consider giving it a โญ๏ธ on GitHub to support my work!

Full Changelog: v1.1.0...v1.2.0


Made by Acris with โค๏ธ