grunt-contrib-csslint is a Grunt plugin that provides CSS linting capabilities using the CSSLint library. It enables developers to automatically check CSS files for potential issues, code quality violations, and adherence to best practices as part of their build process.
npm install grunt-contrib-csslint --save-devAfter installation, enable the plugin in your Gruntfile:
grunt.loadNpmTasks('grunt-contrib-csslint');// Basic configuration in Gruntfile.js
grunt.initConfig({
csslint: {
strict: {
options: {
import: 2
},
src: ['path/to/**/*.css']
},
lax: {
options: {
import: false
},
src: ['path/to/**/*.css']
}
}
});
// Run the task
grunt.registerTask('default', ['csslint']);The plugin is built around these key components:
The main plugin function that registers the 'csslint' Grunt multi-task.
/**
* Main plugin registration function
* @param grunt - Grunt instance
*/
function(grunt: GruntInstance): void;The 'csslint' Grunt multi-task that processes CSS files using CSSLint rules.
/**
* csslint Grunt multi-task for linting CSS files
* Configured via options in Gruntfile.js
*/
grunt.registerMultiTask('csslint', taskDescription, taskFunction);All CSSLint rules are supported as options. Rule values determine enforcement level:
interface CSSLintRuleOptions {
/** Disallow !important declarations */
'important'?: boolean | number;
/** Disallow adjoining classes */
'adjoining-classes'?: boolean | number;
/** Require use of known properties */
'known-properties'?: boolean | number;
/** Disallow box-sizing property */
'box-sizing'?: boolean | number;
/** Beware of box model size issues */
'box-model'?: boolean | number;
/** Disallow overqualified elements */
'overqualified-elements'?: boolean | number;
/** Require properties appropriate for display */
'display-property-grouping'?: boolean | number;
/** Bulletproof font-face declarations */
'bulletproof-font-face'?: boolean | number;
/** Require compatible vendor prefixes */
'compatible-vendor-prefixes'?: boolean | number;
/** Disallow selectors that look like regular expressions */
'regex-selectors'?: boolean | number;
/** Built-in error rule */
'errors'?: boolean | number;
/** Disallow duplicate background images */
'duplicate-background-images'?: boolean | number;
/** Disallow duplicate properties */
'duplicate-properties'?: boolean | number;
/** Disallow empty rules */
'empty-rules'?: boolean | number;
/** Selector max approaching limit */
'selector-max-approaching'?: boolean | number;
/** Require all gradient definitions */
'gradients'?: boolean | number;
/** Require fallback colors */
'fallback-colors'?: boolean | number;
/** Don't use too many font-size declarations */
'font-sizes'?: boolean | number;
/** Don't use too many web fonts */
'font-faces'?: boolean | number;
/** Disallow too many floats */
'floats'?: boolean | number;
/** Disallow star hack */
'star-property-hack'?: boolean | number;
/** Disallow outline:none */
'outline-none'?: boolean | number;
/** Disallow @import */
'import'?: boolean | number;
/** Disallow IDs in selectors */
'ids'?: boolean | number;
/** Disallow underscore hack */
'underscore-property-hack'?: boolean | number;
/** Rules count limit */
'rules-count'?: boolean | number;
/** Disallow qualified headings */
'qualified-headings'?: boolean | number;
/** Selector max limit */
'selector-max'?: boolean | number;
/** Require shorthand properties */
'shorthand'?: boolean | number;
/** Disallow negative text-indent */
'text-indent'?: boolean | number;
/** Headings should only be defined once */
'unique-headings'?: boolean | number;
/** Disallow universal selector */
'universal-selector'?: boolean | number;
/** Disallow unqualified attribute selectors */
'unqualified-attributes'?: boolean | number;
/** Require standard property with vendor prefix */
'vendor-prefix'?: boolean | number;
/** Disallow units for zero values */
'zero-units'?: boolean | number;
/** Disable all unspecified rules when set to false */
'*'?: boolean;
}Rule Value Meanings:
false: Ignore/disable the rule2: Set rule to error level (fails build)interface CSSLintTaskOptions extends CSSLintRuleOptions {
/** Path to .csslintrc file containing rule configuration */
csslintrc?: string;
/** Array of formatter configuration objects */
formatters?: FormatterConfig[];
/** Use absolute file paths in formatter output */
absoluteFilePathsForFormatters?: boolean;
/** Only output errors (suppress warnings) */
quiet?: boolean;
/** Suppress all output (errors and warnings) */
quiet_all?: boolean;
}
interface FormatterConfig {
/** Formatter ID or custom formatter object */
id: string | CustomFormatter;
/** Output file path for formatted results */
dest: string;
}
interface CustomFormatter {
/** Unique formatter ID */
id: string;
/** Initialize formatting output */
startFormat(): string;
/** Format results for a single file */
formatResults(result: CSSLintResult, filename: string, options: any): string;
/** Finalize formatting output */
endFormat(): string;
}Load options from a .csslintrc file with JSON format that supports comments:
// Example .csslintrc file
{
// Enable specific rules
"qualified-headings": true,
"unique-headings": true,
// Disable specific rules
"known-properties": false,
// Set error level rules
"import": 2,
"ids": 2
}Usage Example:
csslint: {
options: {
csslintrc: '.csslintrc'
},
src: ['src/**/*.css']
}Generate formatted output for CI integration and reporting:
/**
* Built-in formatters available
*/
type BuiltInFormatter =
| 'text' // Plain text output
| 'compact' // Compact text format
| 'lint-xml' // XML lint format
| 'csslint-xml' // CSSLint XML format
| 'checkstyle-xml' // Checkstyle XML format
| 'junit-xml'; // JUnit XML formatUsage Examples:
// Multiple formatters with absolute paths
csslint: {
options: {
absoluteFilePathsForFormatters: true,
formatters: [
{id: 'junit-xml', dest: 'reports/csslint_junit.xml'},
{id: 'csslint-xml', dest: 'reports/csslint.xml'}
]
},
src: ['src/**/*.css']
}
// Custom formatter
csslint: {
options: {
formatters: [
{id: require('csslint-stylish'), dest: 'reports/csslint_stylish.xml'}
]
},
src: ['src/**/*.css']
}The task processes files according to standard Grunt file configuration patterns:
// Target with specific files
csslint: {
custom: {
options: {
'import': 0,
'ids': 0
},
files: ['path/to/specific.css']
}
}
// Target with glob patterns
csslint: {
all: {
src: ['src/**/*.css', 'styles/**/*.css']
}
}
// Target with single file
csslint: {
single: 'path/to/single.css'
}The task returns boolean values for Grunt task chaining:
false if any CSS files contain errors (fails the build)undefined (success) if all files are lint-free/**
* CSSLint result structure
*/
interface CSSLintResult {
messages: CSSLintMessage[];
}
interface CSSLintMessage {
/** Error or warning type */
type: 'error' | 'warning';
/** Line number where issue occurs */
line: number;
/** Column number where issue occurs */
col: number;
/** Human-readable message */
message: string;
/** Rule information */
rule: {
/** Rule identifier */
id: string;
/** Rule description */
desc: string;
/** Supported browsers */
browsers: string;
};
}Console Output Format:
L25:C10/**
* Grunt instance interface (simplified)
*/
interface GruntInstance {
registerMultiTask(name: string, description: string, taskFunction: Function): void;
file: {
read(filepath: string): string;
write(filepath: string, contents: string): void;
};
log: {
writeln(message: string): void;
error(message?: string): void;
ok(message?: string): void;
};
verbose: {
write(message: string): void;
writeln(message: string): void;
ok(): void;
or: {
write(message: string): void;
};
};
util: {
pluralize(count: number, singular: string, plural?: string): string;
};
}