← BACK

eslint-cssicorn

Powerful ESLint rules for CSS

JavaScript ⭐ 73

eslint-cssicorn

Powerful ESLint rules for CSS

The rules work with the @eslint/css language plugin.

eslint-plugin-unicorn has more rules that also lint CSS, such as no-zero-fractions and no-shorthand-property-overrides.

Propose a new rule ➡

We do not accept pull requests because of too much AI slop.

Install

npm install --save-dev eslint @eslint/css eslint-cssicorn

Requires ESLint >=10.4, flat config, and ESM.

Usage

Use a preset config or configure each rule in eslint.config.js.

If you don't use a preset, set language: 'css/css' and add the @eslint/css plugin, as shown below.

import css from '@eslint/css';
import cssicorn from 'eslint-cssicorn';
import {defineConfig} from 'eslint/config';

export default defineConfig([
	{
		files: [
			'**/*.css',
		],
		plugins: {
			css,
			cssicorn,
		},
		language: 'css/css',
		rules: {
			'cssicorn/prefer-short-hex-color': 'error',
			'cssicorn/…': 'error',
		},
	},
	// …
]);

Embedded CSS

To lint fenced CSS blocks in Markdown, configure the @eslint/markdown processor. The presets match its extracted .css files. Lint Markdown prose separately.

import markdown from '@eslint/markdown';
import cssicorn from 'eslint-cssicorn';

export default [
	{
		files: [
			'**/*.md',
		],
		plugins: {
			markdown,
		},
		language: 'markdown/commonmark',
		processor: 'markdown/markdown',
	},
	cssicorn.configs.recommended,
];

Rules

💼 Configurations enabled in.
✅ Set in the recommended configuration.
☑️ Set in the unopinionated configuration.
🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.

Name Description 💼 🔧 💡
consistent-compound-selector-order Enforce consistent ordering of compound selector components. ✅ 🔧
consistent-layer-order Enforce consistent ordering of cascade layer statements. ✅ 🔧
consistent-property-order Enforce consistent ordering of CSS properties. 🔧 💡
consistent-value-order Enforce consistent ordering of CSS value components. ✅ 🔧
lowercase Enforce lowercase CSS syntax. ✅ 🔧
no-clamped-values Disallow CSS values that browsers silently clamp. ✅
no-declarations-after-nested-rules Disallow declarations after nested rules. ✅ ☑️
no-deprecated-features Disallow deprecated CSS features. ✅ 🔧 💡
no-descending-specificity Disallow lower-specificity selectors from following higher-specificity selectors that set the same property.
no-disabled-pinch-zoom Disallow touch-action values that disable browser pinch zoom. ✅ 💡
no-duplicate-at-rule-definitions Disallow duplicate named at-rule definitions. ✅
no-duplicate-font-family-names Disallow duplicate font family names. ✅ ☑️ 🔧
no-duplicate-properties Disallow duplicate properties within CSS declaration blocks. ✅ 💡
no-duplicate-selectors Disallow duplicate CSS selectors. ✅ 🔧
no-ineffective-keyframe-declarations Disallow ineffective declarations in keyframes. ✅ ☑️ 🔧
no-ineffective-overrides Disallow state and conditional overrides blocked by cascade priority. ✅
no-ineffective-properties Disallow properties that have no effect given other declarations or shorthand defaults. ✅ ☑️
no-ineffective-selector-properties Disallow properties that cannot affect their selected targets. ✅ ☑️ 🔧
no-ineffective-supports-conditions Disallow supports conditions that do not test their value functions. ✅
no-ineffective-transitions Disallow transition targets that cannot transition under the declared behavior. ✅ ☑️ 💡
no-invalid-media-features Disallow unknown media features, invalid values, and invalid notation. ✅ ☑️
no-invalid-property-references Disallow invalid property references in transitions and will-change. ✅ ☑️
no-layout-animations Disallow animating properties that can affect layout.
no-nesting-with-mixed-specificity Disallow mixed specificity in nesting parents and selector-list pseudo-classes. ✅
no-overflow-axis-coercion Disallow overflow values that are coerced by the other axis. ✅ ☑️
no-redundant-functions Disallow redundant function calls and arguments. ✅ 🔧
no-redundant-longhand-properties Disallow longhand properties that can be combined into a shorthand. ✅ 🔧
no-redundant-nested-style-rules Disallow nested style rules that do not modify the parent selector. ✅ 🔧
no-redundant-nesting-selector Disallow redundant nesting selectors. ✅ 🔧
no-redundant-shorthand-values Disallow redundant values in CSS shorthand properties. ✅ 🔧
no-self-referencing-custom-properties Disallow cyclic dependencies in CSS custom properties. ✅ ☑️
no-unknown-animations Disallow unknown animations.
no-unknown-annotations Disallow unknown and noncanonical CSS annotations. ✅ ☑️ 🔧 💡
no-unknown-pseudo-selectors Disallow unknown pseudo-class and pseudo-element selectors. ✅ ☑️
no-unknown-type-selectors Disallow unknown type selectors. ✅ ☑️
no-unscoped-nesting-selector Disallow unscoped CSS nesting selectors. ✅ ☑️
no-useless-is Disallow unnecessary :is() wrappers. ✅ ☑️ 🔧
no-zero-length-unit Disallow units on zero CSS lengths. ✅ 🔧
prefer-aspect-ratio Prefer aspect-ratio over zero-height percentage-padding workarounds. ✅
prefer-clamp Prefer clamp() over nested min() and max(). ✅ ☑️ 🔧
prefer-current-color Prefer currentcolor over repeating the foreground color. ✅ 💡
prefer-existing-custom-properties Prefer existing custom properties over matching literal values. ✅ 💡
prefer-explicit-viewport-units Prefer explicit viewport units. ✅ 💡
prefer-individual-transform-properties Prefer individual transform properties over transform functions. ✅ 💡
prefer-light-dark Prefer light-dark() over paired light and dark color declarations. ✅ 💡
prefer-media-feature-range-syntax Prefer modern media feature range syntax. ✅ 🔧 💡
prefer-merged-rules Prefer merging adjacent rules with identical declarations or conditions. ✅ 🔧
prefer-modern-syntax Prefer modern CSS color and pseudo-element syntax. ✅ 🔧
prefer-nesting Prefer CSS nesting for structural :is() groups and rules extending an existing parent. ✅ 🔧
prefer-relative-colors Prefer relative colors for alpha variants of existing color custom properties. ✅ 💡
prefer-short-hex-color Prefer short hexadecimal color notation. ✅ 🔧
require-prefers-reduced-motion Require motion effects inside prefers-reduced-motion: no-preference media queries.
require-property-descriptors Require descriptors in CSS @property rules. ✅ ☑️
require-selector-scope Require a positive scoping boundary for every selector.

Preset configs

See the ESLint docs for more information about extending config files.

Note: The preset configs apply to **/*.css files. They also set language: 'css/css' and add the @eslint/css plugin.

Recommended config

This plugin exports a recommended config that enforces good practices.

import cssicorn from 'eslint-cssicorn';
import {defineConfig} from 'eslint/config';

export default defineConfig([
	// …
	cssicorn.configs.recommended,
	{
		files: [
			'**/*.css',
		],
		rules: {
			'cssicorn/no-unknown-animations': 'error',
		},
	},
]);

Unopinionated config

This plugin exports an unopinionated config with bug checks and straightforward simplifications.

import cssicorn from 'eslint-cssicorn';
import {defineConfig} from 'eslint/config';

export default defineConfig([
	// …
	cssicorn.configs.unopinionated,
]);

All config

This plugin exports an all config that enables every rule.

import cssicorn from 'eslint-cssicorn';
import {defineConfig} from 'eslint/config';

export default defineConfig([
	// …
	cssicorn.configs.all,
	{
		files: [
			'**/*.css',
		],
		rules: {
			'cssicorn/prefer-short-hex-color': 'off',
		},
	},
]);

Related