-
Notifications
You must be signed in to change notification settings - Fork 660
☂️ CSS support #984
Comments
One thing that I haven't seen that would be nice is if there are explicitly author-defined things in CSS, like a registered custom property, would be for tooling to support/lint it according to its own definition in CSS/JS. It's possible create custom properties in CSS like this: a {
--demo: blue;
} And there's also the ability for you to register them from CSS with @property --demo {
syntax: '<color>';
inherits: true;
initial-value: blue;
} or in JS CSS.registerProperty({
name: '--demo',
syntax: '<color>',
inherits: true,
initialValue: 'blue'
}) Given one of these definitions, it would be nice if there was tooling that could look at code like the following example and produce error messages that instruct what it needs in order to be valid according to your own definitions of what that custom property is: example {
--demo: 1px;
}
|
@sebmck @ematipico Need help? I have long dreamed of rewriting postcss/stylelint/cssnano (over the years, many problems have accumulated, especially related postcss - lack of opportunities of parsing). Many stylelint rules was written/rewritten by me, cssnano (minificator for CSS) lately supported by me, have worked on CSS formatting in prettier. But I would like to discuss some aspects a little, especial non standard syntax, like |
cc @sebmck @ematipico friendly ping |
Hi @evilebottnawi , at the moment @bitpshr has made a stable base for the CSS parser although there are still some aspects missing (I can't remember the details but there some sub grammars that are not supported yet). Although we could potentially start writing something around linting, which is the first step I think (together with the formatter). About minification/purging, there's nothing yet and having a good input on how to start is always welcome. About non-standard syntax, I don't know if we are ready yet. SASS and LESS are supersets of CSS so if we don't have a stable CSS parser, I don't think we can implement much around SASS and LESS. Theoretically we could start the foundations but I would wait and focus on what's more important. |
We need to implement the following selector syntax: https://www.w3.org/TR/selectors-4/#syntax |
@ematipico Thanks for answer, I'll look at the code and get back to it in near future, maybe we should start with CSS formatter (without scss/less/etc), it should be easy and will allow finish parser, good parser = good linter |
@ematipico Let me know if there's anything I can do to help, either by providing samples of valid CSS syntax, or hunting for things in specs (tokens, productions, etc). I've already got a bunch of tools I use in my own work for parsing or validating pieces of CSS syntax according to the spec :D
And I've got plenty more samples and examples too, here's a list of known-valid CSS custom property values gleaned from the Web Platform Tests: legal css custom property values {
--percentage: 25%;
--number: 37;
--length: 12em;
--time: 75ms;
--function: foo();
--nested-function: foo(bar());
--parentheses: ( );
--braces: { };
--brackets: [ ];
--at-keyword-unknown: @foobar;
--at-keyword-known: @media;
--at-keyword-unknown-block: @foobar {};
--at-keyword-known-block: @media {};
--cdo-at-top-level: <!--;
--cdc-at-top-level: -->;
--semicolon-not-top-level: (;);
--cdo-not-top-level: (<!--);
--cdc-not-top-level: (-->);
} |
|
Currently working on CSS Variables and |
Currently working on Keyframes |
Thank you @tomhodgins , FYI I am going to update our test-fixtures with the example that you pasted here. |
It's fantastic to see so much progress on the CSS parser and formatter!
I can break down the stylelint rules for you. I helped create stylelint, and I'm more than happy to share what we learnt. We split the rules in stylelint into three categories:
The stylistic issue rules check whitespace, case and quotes. (The rules are configurable, but an opinionated formatter would avoid that complexity.) We didn't develop a good solution for automatically fixing long line lengths. Prettier does this well, though. stylelint-order is the most popular stylistic plugin and can order the content of blocks, i.e. properties, nested rules, etc. The limit language feature rules let you enforce non-stylistic code consistency. For example:
These tend to be specific to a team or project, which is why the rules are configurable and not found in the official configs. The possible error rules check for duplicates, overrides and (easy to find) invalid syntax. Full validation is the most requested feature in stylelint and is not something we've been able to do in stylelint itself. For example, flagging that a { color: 10px; } This ties into @tomhodgins suggestion above of validating registered custom properties. CSSTree does validation well, and you can validate property-value pairs in stylelint using the CSSTree stylelint validator plugin. Here is CSSTree's reference for the I hope this quick breakdown of the rules was helpful. I'm happy to fresh out any bits if that'll be useful to you. I'm excited for Rome. As a fan of CSS, it'd be amazing to write linting rules while not also having to maintain a CLI and editor extension just for CSS! They may already be on your radar, but I didn't see the following syntaxes mentioned above: |
Starting working on media queries! |
Fantastic! They may already be on your radar, but I often see the range context from the level 4 specification, and custom media queries and the user preference media features from the level 5 specification in the wild. /* range context */
@media (480px <= width < 768px) {}
/* custom media queries */
@custom-media --narrow-window (max-width: 30em);
@media (--narrow-window) {}
/* user preference media features */
@media (prefers-reduced-motion: reduce) {}
@media (prefers-color-scheme: dark) {} The accessibility community is driving the adoption of user preference media queries. The range context and custom media queries are typically transpiled using postcss-preset-env. |
Thank you for the pointers! This opens up a lot of things, especially what should we support in Rome. If it was for me I would start writing AST nodes and logic without breaks; probably we would need to come up with something. @jeddy3 BTW, do you know how/where to check the actual stage of a specification? Unfortunately I don't know much about how's the bureaucracy around CSS. |
I didn't offhand, but I found this list of current work. The first specification listed is CSS Snapshot 2020, which introduces the process and stages. I tend to dig into a specification when someone requests a new rule in stylelint for a CSS feature I haven't seen before. Even after a few years of building stylelint, I'm still learning about all the things that CSS can do. It's an amazing language. |
All features supported in the CSS language will abide by CSS's syntax, specified here: https://drafts.csswg.org/css-syntax-3/ so if CSS is parsed accurately according to its own syntax, all features should be something we can work with (for example
There are collections of the current drafts being worked on in a couple places like: There are statuses like 'Candidate Recommendation' and 'Draft' etc but they don't work like 'stages' for JS proposals. If you want an unofficial peek at what 'stages' things might be, Jon Neal has a site here with upcoming drafts and roughly (in his estimation) where they're at in a stage-like process: https://github.com/csstools/cssdb |
That's really cool. I assume that's what allowed the explosion of PostCSS plugins that extended CSS. I'm not very familiar with parsers, so I don't know if this is possible, but a granular parser would make it easier to write lint rules. For example, the Given: /* user preference media features */
@media (prefers-reduced-motion: reduce) {}
/* range context */
@media (480px <= width < 768px) {}
/* custom media queries */
@custom-media --narrow-window (max-width: 30em); Is it possible to have |
I'm going to find time to work on the |
I will work on implementing few nodes around |
CSS lint is now enabled on Probably the highlighting part needs to be reviewed and we would need to add few stuff to make the coloring better. We should start discussing which rules we want to implement. We could focus, first, on rules that prevent errors and don't require some configuration. After that we could start working on other rules. This section of the stylelint website is a good starting point. |
That's fantastic!
The rules in this section can be roughly split into two groups:
The first group is made up of:
I believe Rome already handles the Rather than add piecemeal The second group is made up of:
There is also the All of the patterns caught by these rules are valid CSS but are likely mistakes that won't be caught by a validator. Out of these rules, you may want to start with the a {
margin-top: 5px; /* this is overridden */
margin: 10px;
} Not all the a {
--my-prop: 2px;
--my-prop: 4px; /* likely a mistake */
font-size: 16px;
font-size: 1rem; /* likely intentional */
} As such, the It may be best to start with the clearer-cut of these I think users have a love-hate relationship with the I'd place the following rules at the bottom of the list:
Although not in this section, I think the The 3rd party Bringing this and validation together, I'd be fantastic if a user could define their custom properties in one place: /* colors.css */
@property --primary,
@property --accent {
syntax: '<color>';
inherits: true;
}
@property --primary {
initial-value: red;
}
@property --accent {
initial-value: blue;
} And reference them in another: /* component.css */
a {
margin: var(--acent); /* violation - unknown custom property */
margin: var(--accent); /* violation - unexpected `<color>` value for `margin` property */
} I don't know if Rome can lint a source in the broader context of all the sources in the graph, but if it can then it'll leapfrog over what stylelint is currently capable of doing and will open up lots of exciting possibilities! |
This rule will have a lot of limitations, because custom properties hoist, so you can use variable from other files or context, for example |
Lot of amazing feedback! Thank you! I will probably start creating an umbrella issue where I will list the rules that actually makes sense having.
Yes, many rules won't be needed because they are errors in the spec, so we throw diagnostics during the parsing phase of the file. e.g. .style {
width calc(2rem * 2rem / 1rem)
} this syntax will throw a diagnostic error during parsing, because by spec after
The formatter already takes care of adding leading semicolons, but double semicolons are peculiar. We might need to check if it's an error in the spec or not, and if not, we might need a rule.
This is a good case! We should add them to the list! And we could decide to add an auto fix. Thank you!
At the moment the linter works on single files, but Rome has a solid infrastructure with a dependency graph out of the box. We might be able to achieve this, we just need to think how.
I believe in Rome we could eventually achieve this. Not at rule level (lint) but probably at compilation level. Because of the fact that Rome can parse JS, CSS and HTML, and the fact that we have already a dependency graph that works, we might be able to build the correct scopes for CSS and understand when a property is used (or not), where, and if it makes sense having it. It would require lot of work, but I think it's achievable. |
@ematipico just interesting is |
Yes they are! Although range context is not yet. The PR was becoming too big so I decided to cut it short and implementing it later |
Great, as I understand it, in the future we will have minimizer/uglifier too? I understand what |
Releasing internal packages is part of the roadmap! Not sure how and when, but I know that Sebastian wants to do it :) Probably after we craft a decent plugin system. It's one of the main concerns. |
@ematipico Sounds good, hopefully it will come sooner so that we can start this migration as it will take time. Getting more feedback we will fix more bugs faster and implement more features. |
Closing in favour of #2350 |
We already have the basis of a CSS formatter that @bitpshr has built out. Not sure how much more work needs to go into supporting additional syntax and testing.
Linting
What sort of rules do we want? https://stylelint.io/ and https://postcss.org/ would be good references.
The text was updated successfully, but these errors were encountered: