GithubHelp home page GithubHelp logo

stylelint-a11y's Introduction

stylelint-a11y

NPM version npm PRs Welcome Build Status

Installation and usage

yarn add --dev stylelint stylelint-a11y

Create the .stylelintrc.json config file (or open the existing one), add stylelint-a11y to the plugins array and the rules you need to the rules list. All rules from stylelint-a11y need to be namespaced with a11y.

Please refer to stylelint docs for the detailed info on using this linter.

Rules

  • ⭐️ - the mark of recommended rules.
  • ✒️ - the mark of fixable rules.
Rule ID Description
content-property-no-static-value Disallow unaccessible CSS generated content in pseudo-elements
font-size-is-readable Disallow font sizes less than 15px
line-height-is-vertical-rhythmed Disallow not vertical rhythmed line-height
⭐️✒️ media-prefers-reduced-motion Require certain styles if the animation or transition in media features
media-prefers-color-scheme Require implementation of certain styles for selectors with colors.
no-display-none Disallow content hiding with display: none property
no-obsolete-attribute Disallow obsolete attribute using
no-obsolete-element Disallow obsolete selectors using
no-spread-text Require width of text in a comfortable range
⭐️ no-outline-none Disallow outline clearing
no-text-align-justify Disallow content with text-align: justify
⭐️✒️ selector-pseudo-class-focus Require or disallow a pseudo-element to the selectors with :hover

Recommended config

Add recommended configuration by simply adding the following to extends in your stylelint configuration:

stylelint-a11y/recommended

This shareable config contains the following:

{
  "plugins": ["stylelint-a11y"],
  "rules": {
    "a11y/media-prefers-reduced-motion": true,
    "a11y/no-outline-none": true,
    "a11y/selector-pseudo-class-focus": true
  }
}

Since it adds stylelint-a11y to plugins, you don't have to do this yourself when extending this config.

Help out

There work on the plugin's rules is still in progress, so if you feel like it, you're welcome to help out in any of these (the plugin follows stylelint guidelines so most part of this is based on its docs):

  • Create, enhance, and debug rules (see stylelint's guide to "Working on rules").
  • Improve documentation.
  • Chime in on any open issue or pull request.
  • Open new issues about your ideas on new rules, or for how to improve the existing ones, and pull requests to show us how your idea works.
  • Add new tests to absolutely anything.
  • Work on improving performance of rules.
  • Contribute to stylelint
  • Spread the word.

We communicate via issues and pull requests.

There is also stackoverflow, which would be the preferred QA forum.

stylelint-a11y's People

Contributors

baradusov avatar coliff avatar hudochenkov avatar igorkamyshev avatar pascalduez avatar scottgruber avatar silvenon avatar thibaudcolas avatar uncleseneca avatar ybiquitous avatar yozhikm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stylelint-a11y's Issues

a11y/media-prefers-reduced-motion: media-feature-name-no-unknown error

CSS that uses prefers-reduced-motion media query:

html {
  scroll-behavior: smooth;
}

@media screen and (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

.stylelintrc.js uses stylelint-a11y and its rules (including a11y/media-prefers-reduced-motion):

module.exports = {
  'extends': 'stylelint-config-standard',
  'plugins': [
    'stylelint-a11y',
  ],
  'rules': {
    'a11y/media-prefers-reduced-motion': true,
    'a11y/no-outline-none': true,
    'a11y/selector-pseudo-class-focus': true,
    'no-empty-source': null,
    'string-quotes': 'double',
    'at-rule-no-unknown': [
      true,
      {
        'ignoreAtRules': [
          'extend',
          'at-root',
          'debug',
          'warn',
          'error',
          'if',
          'else',
          'for',
          'each',
          'while',
          'mixin',
          'include',
          'content',
          'return',
          'function',
          'tailwind',
          'apply',
          'responsive',
          'variants',
          'screen',
        ],
      },
    ],
  },
};

The prefers-reduced-motion media query still results in lint error:

Unexpected unknown media feature name "prefers-reduced-motion"   media-feature-name-no-unknown

a11y/media-prefers-reduced-motion: doesn't work with mixins

We have a lot of code in our project that does something like this:

@mixin some-mixin {
  transition: all 0.2s ease-out;
  // ... other code
}

and we use those mixins like so:

.some-class {
  @include some-mixin;
  // ... other code
}

It would be useful if the plugin could error out either inside the mixin or where it's used.

`content-property-no-static-value`: Add exceptions for quote values

The content property allows for special keyword values for display quotation marks.

content: open-quote;
content: close-quote;
content: no-open-quote;
content: no-close-quote;

This rule currently highlights these as incorrect from an accessibility POV as it thinks it's static text content.

Is it possible to add an exception for these values which are purely presentational and wouldn't impact accessibility users? Likely as an option (default 'false' to maintain existing functionality) to the rule to allow users more control over whether these are allowed.

[selector-pseudo-class-focus]: Cannot read property 'match' of undefined

TypeError: Cannot read property 'match' of undefined
    at check (/home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/selector-pseudo-class-focus/index.js:96:16)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/selector-pseudo-class-focus/index.js:46:18
    at Array.map (<anonymous>)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/selector-pseudo-class-focus/index.js:45:44
    at /home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:144:26
    at Root.each (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:110:22)
    at Root.walk (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:143:21)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/selector-pseudo-class-focus/index.js:16:10
    at Promise.resolve.then (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/lib/lintSource.js:221:9)
    at <anonymous>

Incorrect peer dependency

Just installed stylelint-a11y as part of a fresh install on a new project using yarn with:

yarn add stylelint stylelint-config-standard stylelint-a11y --dev

Noticed the following in the output of Yarn:

warning " > [email protected]" has incorrect peer dependency "stylelint@^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0".

no-outline-none false positive

tag:focus:not(:focus-visible) {
   outline: none;
}

This triggers the no-outline-none rule. This syntax specifically targets browsers that support focus-visible and have determined that the user is a mouse user.

Correct styling is failing when using nested media queries in SCSS

I'm using the media-prefers-reduced-motion rule, and am having the following issue with the linter:

/* Fails */
.foo {
  transition: all;

  @media (prefers-reduced-motion: reduce) {
    transition: none;
  }
}
/* Works */
.foo {
  transition: all; 
}

@media (prefers-reduced-motion: reduce) {
  .foo {
    transition: none;
  }
}

The SCSS in the first code snippet produces the CSS in the second code snippet, yet the first example fails while the second example succeeds.

[media-prefers-reduced-motion]: Cannot read property 'some' of undefined

TypeError: Cannot read property 'some' of undefined
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:111:31
    at Array.some (<anonymous>)
    at check (/home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:109:41)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:37:24
    at /home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:144:26
    at Root.each (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:110:22)
    at Root.walk (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:143:21)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:16:10
    at Promise.resolve.then (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/lib/lintSource.js:221:9)
    at <anonymous>

add support to stylelint 16 bro

Please support stylelint 16.0.0, the big one

Now the code is in ESM instead of CommonJS

Very good

Stylelint team published docs to know how to migrate with ease.

No need to keep support to commons from now on.

Style lint 16 is not allowed in your package.json. remove this restriction to

Call out statically detectable bad contrast

According to WCAG’s Success Criterion 1.4.3, text should have a contrast ratio of at least 4.5, while large text (which starts at around 24px or 18.67px bold) should have a contrast ratio of at least 3.

Although we cannot statically detect all cases of bad contrast (we cannot even predict what font size will be used, given browser zooming settings), we can detect the worst cases (ratio below 3), and maybe additionally warn for values below a configurable threshold (say, 2.5).

The formulas are here: https://w3c.github.io/wcag/understanding/contrast-minimum.html#dfn-contrast-ratio Here's the implementation in Chrome DevTools: https://source.chromium.org/chromium/chromium/src/+/master:third_party/devtools-frontend/src/front_end/common/ColorUtils.js;l=72-86;drc=91403e7b5c9ae2717db9243d177f8644d0d712be

Rule Proposal

Here I want to tell you a list of rules that could be included in the plugin.

  1. no-outline-none

Covering: 94.99%

.foo:focus { 
   outline: none; 
}
  1. media-high-contrast

Covering: IE, Edge

-ms-high-contrast: MDN
To help people use sites with high contrast mode.

.bar { 
   color: pink; 
} 
@media (-ms-high-contrast) {
  // no color property in a selector is here
}
  1. no-display-none

Covering: full

.baz { 
   display: none; 
}

@evilebottnawi What do you think?

Flag styling obsolete elements and attributes

Hi,

thanks for this stylelint plugin, it WILL help raise awareness about web accessibility among stylelint users! 👍

2 new rules could be about the use of obsolete/deprecated elements (tags) and attributes (in HTML5) as selectors and flagging them.
The priority is to lint HTML for that and it's also better suited in a project like aXe but it'd also be nice to detect those in stylesheets: it means either one is styling things that shouldn't be in the markup or if things aren't in the markup anymore that there are unused rules (to be removed).

Examples of elements that have always caused accessibility problems: marquee, strike, big, blink.
When a user wants to customize a site's appearance with its user sylesheet, center and font elements are harder to manage (CSS should be used for styling, not markup). Same for a loooong list of attributes like [border] and [align]…

Here's a comprehensive list of obsolete elements and attributes: a11y.css / _obsolete.css created by @ffoodd 👋 (reformatted in this gist). Most of them aren't that problematic in regards to web accessibility but all of them are obsolete, either still conforming or non-conforming in HTML 5 so why one would still use them?
Such a list and the choice of flagging or not each one is opinionated and that could be a problem, so your point of view and from others is very welcome. 😄

Proposed rule names: a11y/no-obsolete-element and a11y/no-obsolete-attribute?

Existing rule selector-type-no-unknown](https://stylelint.io/user-guide/rules/selector-type-no-unknown/) only flagged in the above link bgsound, noframes, nextid, multicol and nobr (which is kind of expected because an element like blink does exist).

Relevant past discussion: Bug: Various valid selector types incorrectly reporting as unknown type selectors
Another solution would be for stylelint to create something like selector-element-blacklist and selector-attribute-blacklist but then it'd be a hassle to add manually an array of elements and attributes or would need yet another config like stylelint-config-obsolete to see these rules adopted.

I compiled links to relevant WCAG 2.1 principles and techniques:

Possible to detect global prefers-reduced-motion: reduce?

When using https://hankchizljaw.com/wrote/a-modern-css-reset/ it globally turns off all animations and transitions if prefers-reduced-motion: reduce is set, see below:

/* Remove all animations and transitions for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
  /* We are relaxing the `declaration-no-important` here
     because we want to ensure that code further down the
     cascade will adhere to this accessibility enhancement */
  /* stylelint-disable declaration-no-important */
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Thing is, this plugin does not know that and so if you have something like the following in a different stylesheet:

transform-origin: 50%;
transition: transform 0.3s;

It will cause an error around the use of reduced motion. I imagine detecting this might be very problematic but, could there be an additional value one can set other than false, perhaps global?

So, then one can do

"rules": {
  ...
  "a11y/media-prefers-reduced-motion": global
}

instead of:

"rules": {
  ...
  "a11y/media-prefers-reduced-motion": false
}

This is not a deal-breaker but conveys intent a bit more clearly i.e. I am not turning the rule off and ignoring the guidance but, instead, have a global reset that already turns it all off. Would appreciate your thoughts on this.

Missing recommended.js within the published archive file

Hi, I noticed recommended.js is missing within the published archive file to npm.

Reproduction

Run the following commands on your terminal:

  1. curl -O $(npm v stylelint-a11y dist.tarball)
  2. tar -xzvf stylelint-a11y-*.tgz
  3. ls package/recommended.js => ls: package/recommended.js: No such file or directory

Environment

stylelint-a11y version: 1.1.10 (latest on 2019-04-06)

I would be happy if you would check it. Thanks.

[Feature request] Add option to use with PostCSS custom-media-queries

First of all, thank you for this plugin!
It helps me to pay attention to small details, which can affect accessibility.

I am using PostCSS preset env.
One of the features I use is custom media queries.
With this, I have "aliased" the syntax to write less code and save the writing time:

@custom-media --motion (prefers-reduced-motion: no-preference);
@custom-media --no-motion (prefers-reduced-motion: reduce);

With this, I can write queries for specific selectors like this:

@media (--motion) {
    a {
        transition: all 1s ease-in-out;
    }
}

The problem is, your plugin doesn't recognize the custom-defined media queries.
Therefore I would like to have an option to add an alternative alias, so the linter will not complain about it.

For example:

// .stylelintrc.js

module.exports = {
    	extends: ["stylelint-a11y/recommended"],
    	
    	plugins: ["stylelint-a11y"],
    	
    	rules: {
    	    "a11y/media-prefers-reduced-motion": [true, {
    	        customMediaQueries: {
    	            motion: "--motion",
    	            noMotion: "--no-motion"
    	        },
    	    }],
    	}
};

License

I can't find license file in repo. Maybe you may adding it?

Improve a11y/media-prefers-reduced-motion error message

The current error message for a11y/media-prefers-reduced-motion is:

`Expected ${selector} is used with @media (prefers-reduced-motion)`

expected: selector => `Expected ${selector} is used with @media (prefers-reduced-motion)`,

I think it would be more correct to use this as the error message:

`Expected ${selector} to be used with @media (prefers-reduced-motion)`

a11y/media-prefers-reduced-motion doesn't detect override for rule with multiple selectors

These rules trigger an error with a11y/media-prefers-reduced-motion:

.Zoom-img,
.Zoom-wrap {
  position: relative;
  transition: all var(--Zoom-transition);
  z-index: 1;
}

@media screen and (prefers-reduced-motion) {
  .Zoom-img,
  .Zoom-wrap {
    transition: none;
  }
}

Modifying the above to rules with single selectors gets rid of the error:

.Zoom-wrap {
  position: relative;
  transition: all var(--Zoom-transition);
  z-index: 1;
}

@media screen and (prefers-reduced-motion) {
  .Zoom-wrap {
    transition: none;
  }
}

So it seems that this rule does not parse css rules with multiple selectors correctly. Neither of the above cases should return a linting error.

stylelint 12.x as peer dependency

Hi,

stylelint 12.0.0 was released but do you have a plan to update the peer dependency?

"stylelint": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0"

I get the following error when installing stylelint@12 and stylelint-a11y. 😢

npm ERR! peer dep missing: stylelint@^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0, required by [email protected]

It would be great if you could consider it.
Thanks.

Does it work with SASS?

I am using a recommended config. I've configured WebStorm. Here is an error I get:

TypeError: Cannot read property 'toLowerCase' of undefined
    at ~/projects/my-project/node_modules/stylelint-a11y/dist/rules/no-spread-text/index.js:66:17
    at Array.map (<anonymous>)
    at nodesProbablyForText (~/projects/my-project/node_modules/stylelint-a11y/dist/rules/no-spread-text/index.js:65:6)
    at ~/projects/my-project/node_modules/stylelint-a11y/dist/rules/no-spread-text/index.js:27:24
    at ~/projects/my-project/node_modules/postcss/lib/container.js:237:28
    at ~/projects/my-project/node_modules/postcss/lib/container.js:144:26
    at Root.each (~/projects/my-project/node_modules/postcss/lib/container.js:110:22)
    at Root.walk (~/projects/my-project/node_modules/postcss/lib/container.js:143:21)
    at Root.walkRules (~/projects/my-project/node_modules/postcss/lib/container.js:235:25)
    at ~/projects/my-project/node_modules/stylelint-a11y/dist/rules/no-spread-text/index.js:16:10

sass file:

.x__y-z {
  .gr-col {
    position: relative;
    padding-right: 1rem;
    padding-left: 1rem;
    min-height: .0625rem;
    width: 100%;

    &__1 {
      flex-grow: 0;
      flex-shrink: 0;
      flex-basis: 100%;
      max-width: 100%;
      -ms-flex-positive: 0;
      -ms-flex-negative: 0;
      -ms-flex-preferred-size: 100%;
    }

    &__gutter{
      &--0 {
        padding-right: 0;
        padding-left: 0;
      }
    }
  }
}

Does it work with SASS?

[media-prefers-reduced-motion]: Cannot read property 'some' of undefined

image

TypeError: Cannot read property 'some' of undefined
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:110:31
    at Array.some (<anonymous>)
    at check (/home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:109:41)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:37:24
    at /home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:144:26
    at Root.each (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:110:22)
    at Root.walk (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/node_modules/postcss/lib/container.js:143:21)
    at /home/stanislav/projects/stylelint-a11y-demo/node_modules/stylelint-a11y/dist/rules/media-prefers-reduced-motion/index.js:16:10
    at Promise.resolve.then (/home/stanislav/.nvm/versions/node/v8.11.2/lib/node_modules/stylelint/lib/lintSource.js:221:9)
    at <anonymous>

Do not fail on transition: none

@YozhikM maybe we should not show error on none value of transition in media-prefers-reduced-motion? Anyway, user disable transition.

Also, we should update the example in rule’s docs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.