Dynamic color of Starlight SVG logo #2070
-
Hi there! ContextI followed the guidelines in Customizing Starlight > Add your logo to set up my logo in the documentation. Additionally, I referred to Customizing Starlight > Light and dark logo variants to implement different renderings for light and dark modes. Everything works perfectly. However, since my logo is a simple, single-color SVG, I wanted to use only one SVG file. Using two separate files seemed unnecessary when the color could be changed dynamically via a CSS variable. I experimented with different methods, such as applying I tried another approach to test feasibility:: <svg viewBox="0 0 100 78" xmlns="http://www.w3.org/2000/svg" fill="currentcolor">
<path d="..." />
</svg> .site-title {
filter: brightness(0) saturate(100%) invert(38%) sepia(96%) saturate(2502%) hue-rotate(7deg) brightness(91%) contrast(104%);
/* Adjust the filter values to match your desired color */
} This time, the color changed successfully. AnalysisIn the final DOM, the SVG is not declared directly. Instead, it is used as the source of an <img class="astro-m46x6ez3" alt="" src="/@fs/Users/xxx/project/src/assets/logo.svg?origWidth=100&origHeight=78&origFormat=svg" width="100" height="78" data-astro-source-file="/Users/xxx/project/node_modules/@astrojs/starlight/components/SiteTitle.astro" data-astro-source-loc="12:6"> It seems that the QuestionAre you aware of any other techniques to achieve this (maybe I've missed something obvious), or is this approach a dead-end? If this is not feasible, do you think it would be worthwhile to change how the logo is integrated into the Starlight documentation? For instance, allowing optionally the use of an SVG directly rather than embedding it as a source of an It's not a major issue since loading two SVG files for light and dark modes is still possible, but I wanted to discuss this use case. This is not a high priority. If you don't have time to answer or analyze this, please don't worry about it :) Thanks for your time, and your work on Starlight 🌟 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Thanks for the feedback 🙌 Just for reference, this is a bit related to this discussion. Sharing only as a workaround, you can now use a component override to replace the built-in ---
// src/components/SiteTitle.astro
import type { Props } from '@astrojs/starlight/props'
const { siteTitle, siteTitleHref } = Astro.props;
---
<a href={siteTitleHref} class="site-title sl-flex">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<g fill="#09090b">
<path d="..." transform="..."/>
<path d="..." transform="..."/>
</g>
</svg>
<span class="sr-only">
{siteTitle}
</span>
</a>
<style>
.site-title {
align-items: center;
gap: var(--sl-nav-gap);
font-size: var(--sl-text-h4);
font-weight: 600;
color: var(--sl-color-text-accent);
text-decoration: none;
white-space: nowrap;
}
svg {
height: calc(var(--sl-nav-height) - 2 * var(--sl-nav-pad-y));
width: auto;
max-width: 100%;
object-fit: contain;
object-position: 0 50%;
}
/* Change the fill color in dark mode. */
:global([data-theme='dark']) path {
fill: #fafafa;
}
</style> This approach should work in all browsers (even Safari), for example here is the result in Safari: demo.mp4Note that as mentioned by Chris, this approach optimize first site visit, but de-optimize any future navigations which would have benefited from caching the image. However, this could work fine for small SVGs which should compress pretty well with gzip. |
Beta Was this translation helpful? Give feedback.
Thanks for the feedback 🙌
Just for reference, this is a bit related to this discussion.
Sharing only as a workaround, you can now use a component override to replace the built-in
<SiteTitle>
component to inline your SVG (make sure to run it through a website like SVGOMG to optimize it first) and add a CSS rule to change its fill color in dark mode for example.