Clear and concise description of the problem
the current approach for dual themes is quite clever indeed, but it can be problematic in a few ways.
- it relies on implementation details like
.shiki and span selectors. not a deal-breaker.
- it could get unwieldy/verbose when considering additional themes (e.g. high-contrast). also not a deal-breaker. 🤷
- it relies on
!important, which is pretty much deprecated in this day and age of cascade layers. As a user, it is important (ha!) to me that i have control over the cascade, as i might need to change the colors for particular cases (such as text highlighting, print stylesheets, or forced colors mode).
for reference, here is the css currently needed from the user's side for switching themes:
@media (prefers-color-scheme: dark) {
.shiki {
background-color: var(--shiki-dark-bg) !important;
color: var(--shiki-dark) !important;
& span {
color: var(--shiki-dark) !important;
}
}
}
Suggested solution
(edit: make sure to see update at the end)
i was just thinking about this, and realized that the space toggle technique would be a good fit for this use case, as it would allow users to switch values with a single css declaration.
@media (prefers-color-scheme: dark) {
:root {
--is-shiki-dark: var(--yes);
}
}
(where --yes: initial; is just a convenience constant)
the inline style implementation would look like this, with full support for complex textmate grammar.
<pre style="--is-shiki-dark: /* no */;">
...
<span style="color: var(--is-shiki-dark, #ECEFF4) #6F42C1;">
this is already very good, but we can take this idea further:
-
for full control over the cascade, a custom property could be used instead of color.
- <span style="color: var(--is-shiki-dark, #ECEFF4) #6F42C1;">
+ <span style="--shiki-color: var(--is-shiki-dark, #ECEFF4) #6F42C1;">
and shikiji could ship with a small stylesheet, which can be imported into user's desired cascade layer:
:root {
--no: ;
--yes: initial;
--is-shiki-dark: var(--no);
}
.shiki {
background-color: var(--shiki-bg);
color: var(--shiki-color);
& span {
color: var(--shiki-color);
}
}
(this --shiki-color is an implementation detail that could be obscured/minified into something like --_)s-c. the user only needs to care about the public api, which is --is-shiki-dark)
-
for supporting multiple themes, cyclic dependency space toggles can be used instead of regular space toggles.
<pre>
...
<span style="
--_s-c-light: hotpink;
--_s-c-dark: red;
--_s-c-hc-light: black; /* hc means "high contrast", _ means implementation detail */
--_s-c-hc-dark: white;
">
and shikiji would ship with this small stylesheet that can be imported inside or outside a cascade layer.
:root {
--shiki-theme: var(--shiki--light);
--shiki--light: var(--shiki-theme,);
--shiki--dark: var(--shiki-theme,);
--shiki--hc-light: var(--shiki-theme,);
--shiki--hc-dark: var(--shiki-theme,);
}
.shiki,
.shiki span {
color:
var(--shiki--light, var(--_s-c-light))
var(--shiki--dark, var(--_s-c-dark))
var(--shiki--hc-light, var(--_s-c-hc-light))
var(--shiki--hc-dark, var(--_s-c-hc-dark));
}
finally, the user only needs to set --shiki-theme in their own stylesheet.
:root {
--shiki-theme: var(--shiki--light);
@media (prefers-contrast: more) {
--shiki-theme: var(--shiki--hc-light);
}
@media (prefers-color-scheme: dark) {
--shiki-theme: var(--shiki--dark);
}
@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
--shiki-theme: var(--shiki--hc-dark);
}
}
here's a small demo showing this technique in action: stackblitz.com/edit/js-txy3pa
let me know what you think or if i can clarify anything.
Update
As of 3 minutes ago, there is support for multiple themes, complete with the ability to modify prefixes. This makes the scope of this change much smaller :D At this point, I would be ok with just replacing inline color style with --shiki-light, so that !important is not necessary in the custom css. Everything else could be left upto the user.
Alternative
css-variables theming, but as i understand this makes it difficult to achieve full support for complex syntax highlighting, so not ideal.
Additional context
No response
Validations
Clear and concise description of the problem
the current approach for dual themes is quite clever indeed, but it can be problematic in a few ways.
.shikiandspanselectors. not a deal-breaker.!important, which is pretty much deprecated in this day and age of cascade layers. As a user, it is important (ha!) to me that i have control over the cascade, as i might need to change the colors for particular cases (such as text highlighting, print stylesheets, or forced colors mode).for reference, here is the css currently needed from the user's side for switching themes:
Suggested solution
(edit: make sure to see update at the end)
i was just thinking about this, and realized that the space toggle technique would be a good fit for this use case, as it would allow users to switch values with a single css declaration.
(where
--yes: initial;is just a convenience constant)the inline style implementation would look like this, with full support for complex textmate grammar.
this is already very good, but we can take this idea further:
for full control over the cascade, a custom property could be used instead of
color.and shikiji could ship with a small stylesheet, which can be imported into user's desired cascade layer:
(this
--shiki-coloris an implementation detail that could be obscured/minified into something like--_)s-c. the user only needs to care about the public api, which is--is-shiki-dark)for supporting multiple themes, cyclic dependency space toggles can be used instead of regular space toggles.
and shikiji would ship with this small stylesheet that can be imported inside or outside a cascade layer.
finally, the user only needs to set
--shiki-themein their own stylesheet.here's a small demo showing this technique in action: stackblitz.com/edit/js-txy3pa
let me know what you think or if i can clarify anything.
Update
As of 3 minutes ago, there is support for multiple themes, complete with the ability to modify prefixes. This makes the scope of this change much smaller :D At this point, I would be ok with just replacing inline
colorstyle with--shiki-light, so that!importantis not necessary in the custom css. Everything else could be left upto the user.Alternative
css-variablestheming, but as i understand this makes it difficult to achieve full support for complex syntax highlighting, so not ideal.Additional context
No response
Validations