Make new CSS preprocessor #59
Labels
No Label
admins only
bug
design
duplicate
gimme feedback
good first issue
hmmmm
invalid
reference
wontfix
No Milestone
No Assignees
1 Participants
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: hmn/hmn#59
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
We want to get rid of SCSS (#8), but rather than just throwing out the features of SCSS entirely, I want us to have a more minimal CSS preprocessor.
Declaration nesting is the most obvious feature, and worth doing on its own. Turns out there is a draft spec for this now, but it makes a lot of stupid decisions and we can do better: https://drafts.csswg.org/css-nesting/
Arithmetic expressions are convenient too.
Nesting
There's no point in requiring
&
at the beginning of every nested rule. The official CSS draft indicates that parsing ambiguities sometimes require large amounts of lookahead in some cases, making it unsuitable for runtime. We are not doing this at runtime, and furthermore, we can just avoid stupid ambiguous CSS.Here's how ours should work:
Parsing rules vs. declarations
Broadly speaking, I think it should be pretty easy to tell the difference between rules and declarations by just looking ahead to a
;
or a{
. This is somewhat naive, but should be good enough.Nesting syntax
&
will be replaced with:is(<parent selector>)
.&
will be implicitly prefixed by&
(with a space!) before processing step 1.Example:
Notice that the
:hover
rule is like& :hover
instead of&:hover
.Some expressions could and should be simplified, such as any case where an
:is
contains only a single selector and occurs at the beginning of an expression. For example:(Unless this messes with selector precedence in some way? But I hope not.)
There are probably many other little optimizations to discover as we go.
Media queries
SCSS allows you to define media queries inside declarations. This is quite convenient, and shouldn't be hard to deal with as long as we can parse the
@media
stuff.Variables & expressions
Preprocessor variables and expressions are occasionally quite useful. For example, Tachyons (a CSS utility library we use) defines several SCSS variables for all the preset spacing it uses. We can (and often do) reuse those variables in our own utility style declarations:
We should support variables with exactly the same syntax. Variables should be scoped to the block they are declared in, and are allowed at the top level.
We should also support compile-time arithmetic expressions like SCSS, but without the very stupid decisions that the SCSS people are making.
In our preprocessor, any compile-time arithmetic should be delimited by
#calc()
, e.g.#calc($spacing-medium / 2)
. The idea is to have a compile-time version of CSS'scalc
.The behavior of
#calc
should closely mimic CSScalc
, e.g. supporting+
,-
,*
, and/
, and requiring space around operators. It should support values of all CSS unit types. It should support compile-time variables ($foo
) but should not support CSS runtime variables (var()
).Custom functions
We should be able to create custom functions in our Go code that we can call from our CSS. For example, we currently have a SCSS function
px2rem
that converts a pixel value torem
(assuming1rem
is16px
). That would be nice to preserve in the form#px2rem(60px)
.Other syntax
Line comments are allowed and converted to block comments.
bvisness referenced this issue2022-06-24 22:07:57 +00:00
Here's a test corpus...this isn't necessarily 100% authoritative but I think it shows what we'd like to do, roughly. (It would be fine if it doesn't get exactly this output, since some of the handling of
:is
is pretty subtle.)Not only is our current SCSS compiler extremely slow, but it also no longer works with new versions of Go: https://github.com/wellington/go-libsass/issues/84
This is probably a higher priority now.
Interestingly, it seems that the official declaration nesting syntax is improving. They seem to have walked back
@nest
, which was the most obviously terrible part of the proposed spec. Furthermore, there is continuing discussion on relaxing the syntax further: https://github.com/w3c/csswg-drafts/issues/7961It now might actually be worth supporting the official declaration nesting syntax, so that we get the benefits of compatibility with other tools (e.g. disabling the unfolding of nested declarations in dev so browser dev tools can give a better experience).