Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Rule: baselineWidelyAvailable #26

Open
cheerfuloriole opened this issue Nov 30, 2024 · 5 comments · May be fixed by #33
Open

New Rule: baselineWidelyAvailable #26

cheerfuloriole opened this issue Nov 30, 2024 · 5 comments · May be fixed by #33
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion feature

Comments

@cheerfuloriole
Copy link

cheerfuloriole commented Nov 30, 2024

Rule details

Enforce Baseline Browser Support

What type of rule is this?

Warns about a potential problem

Example code

{
  "baselineWidelyAvailable": true,
  "baselineNewlyAvailable": false,
  "rules": {
    "css/no-invalid-properties": [
      "error",
      {
        "allowed-properties": [
          "text-wrap: pretty",
          "::view-transition"
        ]
      }
    ]
  }
}

Additional comments

I’m not entirely sure how ESLint works under the hood, and while I’d love to contribute, I don’t feel quite ready to tackle that just yet. I hope this issue doesn’t overcomplicate your vision, and if it’s not quite right, feel free to disregard it. I just thought it would be worth sharing because it’s exactly what I need in a CSS linter.

Scenario: Maintainers Setting Boundaries

User Story

As a maintainer, I want contributors to use a consistent subset of CSS features supported across major browsers. This helps keep the project manageable, onboard new contributors efficiently, and maintain evolving CSS best practices.

Background/Description

Maintainers want to ensure their CSS only uses features supported by "Baseline Widely Available" (web.dev/baseline)—a concept for consistent browser support across major platforms. While browsersl.ist doesn’t yet support this natively, the following configuration can define an approximate range:

{
  "browserslist": [
    "Chrome > 0 and last 2.5 years",
    "Edge > 0 and last 2.5 years",
    "Firefox > 0 and last 2.5 years",
    "Safari > 0 and last 2.5 years"
  ]
}

This range ensures features work consistently across all four core browsers while considering features widely available over the past 2.5 years.

Baseline Widely Available

With baselineWidelyAvailable set to true, the linter will flag unsupported CSS. For example, if a developer uses a property like -ms-high-contrast-adjust or a new feature only supported in Chrome, the linter will identify it as out of scope. This ensures that contributors stick to CSS features widely supported across major browsers.

“baselineWidelyAvailable”: true

Baseline Newly Available

If a maintainer trusts their contributors to use progressive enhancements—CSS features that gracefully degrade in unsupported browsers—they can set baselineNewlyAvailable to true. This allows contributors to use newer CSS properties as long as they are supported by all four major browsers, even if not yet "widely available."

“baselineNewlyAvailable”: true

Allowed Properties

For maintainers who need some flexibility, rules can be defined. The "allowed-properties" list allows specific CSS properties to be used, even if they are not widely supported.

{
  "baselineWidelyAvailable": true,
  "baselineNewlyAvailable": false,
  "rules": {
    "css/no-invalid-properties": [
      "error",
      {
        "allowed-properties": [
          "text-wrap: pretty",
          "::view-transition"
        ]
      }
    ]
  }
}

Conclusion

What I like about using Baseline, or at least browsersl.ist, is that it helps contributors understand the target audience better, know where to focus cross-browser troubleshooting, and automate parts of development to reduce manual work.

@cheerfuloriole cheerfuloriole changed the title New Rule: (fill in) New Rule: baselineWidelyAvailable Nov 30, 2024
@fasttime fasttime added this to Triage Dec 1, 2024
@github-project-automation github-project-automation bot moved this to Needs Triage in Triage Dec 1, 2024
@nzakas
Copy link
Member

nzakas commented Dec 2, 2024

I think this is a good idea, we just need to think through what the right user experience is and then find a good data source.

I was pointed to this package when I asked online:
https://www.npmjs.com/package/web-features

I haven't had time to dig into that yet. We'd like need to do some preprocessing on the data to make it more performant rather than shipping the entire package along with the ESLint plugin.

@nzakas nzakas added the accepted There is consensus among the team that this change meets the criteria for inclusion label Dec 2, 2024
@nzakas nzakas moved this from Needs Triage to Evaluating in Triage Dec 2, 2024
@jeddy3
Copy link

jeddy3 commented Dec 2, 2024

In terms of user experience, some people use tooling to lower syntax for their target browsers, either using:

i.e., they author some syntax regardless of baseline.

I don't have a sense of the split between people doing this and those wanting to author directly to one of the baselines. I suspect some people pragmatically mix it up, choosing syntax lowering for some features and authoring directly to a baseline for others.

It'd be great to find a way to cater for these people, too.


It feels like checking validity against the specs and checking against browser support are two separate concerns. Would this be implemented as a new rule? I'm unfamiliar with ESLint's conventions, but that'd provide a nice range of safety nets:

  • css/no-invalid-properties and css/no-invalid-at-rules for spec validity
  • css/no-unsupported-features for flagging features unsupported by the target browsers via baseline or browserlist
  • no-restricted-syntax for restricting syntax that's both valid and supported by the target browsers

For example, given:

rules: {
  "css/no-invalid-properties": "error",
  "css/no-unsupported-features": "error", // configured to Baseline Widely Available somehow
  "no-restricted-syntax": [
    "error",
    {
      selector: "Declaration[property=content-visibility] Identifier[name=auto]",
      message: "Our team doesn't use the  'auto' value for the 'content-visibility' property",
    },
  ],
},

You get:

a {
  content-visibility: /* flagged by `css/no-unsupported-features` as newly available */
    red; /* flagged by `css/no-invalid-properties` as an invalid value for content-visibility */
  content-visibility: auto; /* flagged by `no-restricted-syntax` as user restricted syntax */
}

Rules like use-logical may tie into baseline (#13 (comment)).


It's fantastic to see performance being a consideration! The Stylelint stylelint-no-unsupported-browser-features plugin, which uses doiuse (caniuse database and browserslist under the hood) can be slow.

@nzakas
Copy link
Member

nzakas commented Dec 2, 2024

It feels like checking validity against the specs and checking against browser support are two separate concerns. Would this be implemented as a new rule?

Yes, that's the idea.

@nzakas
Copy link
Member

nzakas commented Dec 6, 2024

I've been digging through the web-features data, and the good news is that it has all of the baseline data. The bad news is that it doesn't really provide any syntax to reference, just descriptions, so it's difficult to tease out the data.

After playing around for a bit, I did manage to find a way to extract:

  • property names
  • at rule names

Here's an example of what the data looks like:
https://gist.github.com/nzakas/5bbc9eab6900d1e401208fa7bcf49500


I think (not 100% sure yet) that the right approach might actually be to create a baseline in languageOptions. What I can do is use https://www.npmjs.com/package/@webref/css and then filter out anything that's not in the specified baseline. I think, at that point, no-invalid-properties and no-invalid-at-rules would correctly report anything that wasn't in the specified baseline. Need to dig into this a bit more.

nzakas added a commit that referenced this issue Dec 12, 2024
@nzakas nzakas linked a pull request Dec 12, 2024 that will close this issue
1 task
@nzakas
Copy link
Member

nzakas commented Dec 12, 2024

I put together a PR:
#33

Take a look and let me know what you think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion feature
Projects
Status: Evaluating
Development

Successfully merging a pull request may close this issue.

3 participants