安装 stylelint
npm install --save-dev stylelint stylelint-config-vusion
然后创建.stylelintrc
文件:
{
"extends": "stylelint-config-vusion"
}
使用插件 vscode-stylelint
/* stylelint配置 */
"stylelint.enable": true,
"css.validate": false,
"scss.validate": false,
说明:
- 语气:强制 > 要求 == !禁止 > 尽量 > 推荐 == !不推荐;
- 🔧表示 StyleLint 可以使用自动修复。
/* ✗ bad */
a {
color:white;
display: none;
}
/* ✓ good */
a {
color: white;
}
/* ✗ bad */
\t\t
/* ✓ good */
a {}
no-missing-end-of-source-newline
/* ✗ bad */
a {
color: pink;
}
/* ✓ good */
a {
color: pink;
}
custom-property-empty-line-before, function-max-empty-lines, value-list-max-empty-lines, declaration-empty-line-before 🔧, TODO:规则没开 rule-empty-line-before, at-rule-empty-line-before🔧
/* ✗ bad */
a {} @media {}
/* ✓ good */
a {}
declaration-block-semicolon-newline-before, declaration-block-semicolon-space-after, declaration-block-semicolon-space-before 🔧, at-rule-semicolon-newline-after🔧, at-rule-semicolon-space-before, selector-list-comma-newline-after, selector-list-comma-newline-before, selector-list-comma-space-after, selector-list-comma-space-before🔧, value-list-comma-newline-after, value-list-comma-newline-before, value-list-comma-space-after, value-list-comma-space-before, function-comma-newline-after, function-comma-newline-before, function-comma-space-after, function-comma-space-before, media-query-list-comma-newline-after, media-query-list-comma-newline-before, declaration-colon-newline-after, media-query-list-comma-space-after, media-query-list-comma-space-before, declaration-colon-newline-after, declaration-colon-space-after, declaration-colon-space-before, media-feature-colon-space-after, media-feature-colon-space-before
/* ✗ bad */
a ,b
,
span {
transform: translate(1
,1)
;top: 0;left: 0;
color :pink
}
@media (max-width :600px) {}
@import url("x.css") ; a {}
/* ✓ good */
a, b, span {
transform: translate(1,1);
top: 0;
left: 0;
color: pink;
}
@media (max-width: 600px) {}
@import url("x.css");
a {}
selector-attribute-brackets-space-inside, selector-pseudo-class-parentheses-space-inside, function-parentheses-space-inside, media-feature-parentheses-space-inside, function-whitespace-after
/* ✗ bad */
input:not( [ type= "submit"] ) {}
[ target ] {}
@media ( max-width:600px) {}
/* ✓ good */
input:not([type="submit"]) {}
[target] {}
@media (max-width: 600px) {}
block-closing-brace-empty-line-before, block-closing-brace-newline-after,
block-closing-brace-space-before, block-opening-brace-newline-after, block-opening-brace-newline-before, block-opening-brace-space-after, block-opening-brace-space-before🔧
/* ✗ bad */
a{color: pink;
top: 0;
}b
{color: pink;}
/* ✓ good */
a {
color: pink;
top: 0;
}
b { color: pink; }
/* ✓ bad */
a { }
/* ✓ good */
a { color: pink; }
selector-attribute-operator-space-after, selector-attribute-operator-space-before, media-feature-range-operator-space-after, media-feature-range-operator-space-before, function-calc-no-unspaced-operator
/* ✗ bad */
[ target ="_blank"] {}
a { top: calc(1px+2px); }
@media (width >=600px) {}
/* ✓ good */
[target="_blank"] {}
a { top: calc(1px + 2px); }
@media (width >= 600px) {}
selector-combinator-space-after🔧, selector-combinator-space-before🔧, selector-descendant-combinator-no-non-space
/* ✗ bad */
a +b { color: pink; }
a>b { color: pink; }
.foo .bar {}
/* ✓ good */
a + b { color: pink; }
a> b { color: pink; }
.foo .bar {}
declaration-bang-space-after, declaration-bang-space-before,
at-rule-name-case🔧, selector-type-case, selector-pseudo-element-case, selector-pseudo-class-case, property-case, value-keyword-case, unit-case, function-name-case, color-hex-case, media-feature-name-case
/* ✗ bad */
@Charset 'UTF-8';
A {
Display: BLOCK;
Width: 1PX;
height: Calc(5% - 10em);
color: #DEF;
}
A:HOVER {}
LI::BEFORE {}
:ROOT {}
@media (MIN-WIDTH: 700px) {}
/* ✓ good */
@charset 'utf-8';
a {
display: block;
width: 1px;
height: calc(5% - 10em);
color: #def;
}
a:hover {}
li::before {}
:root {}
@media (min-width: 700px) and (orientation: landscape) {}
declaration-block-trailing-semicolon🔧, no-extra-semicolons
/* ✗ bad */
.case { font-size: 16px; color: red }
@import "x.css";;
/* ✓ good */
.case { font-size: 16px; color: red; }
@import "x.css";
/* ✗ bad */
[title=flower] {}
/* ✓ good */
[target="_blank"] {}
/* ✗ bad */
a { font-family: Times New Roman, Times, serif; }
/* ✓ good */
a { font-family: 'Times New Roman', Times, serif; }
selector-pseudo-element-colon-notation🔧
/* ✗ bad */
a:before { color: pink; }
/* ✓ good */
a::before { color: pink; }
/* ✗ bad */
#wrapper a { color: pink; }
a { color: gray; }
/* ✓ good */
a { color: gray; }
#wrapper a { color: pink; }
declaration-block-single-line-max-declarations
/* ✗ bad */
a { color: pink; top: 3px; background: url('./test.png'); }
/* ✓ good */
a { color: pink; top: 3px; }
a {
color: pink;
top: 3px;
background: url('./test.png');
}
declaration-block-no-redundant-longhand-properties, shorthand-property-no-redundant-values🔧
/* ✗ bad */
a {
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
padding-right: 10px;
}
a { margin: 1px 1px; }
/* ✓ good */
a {
padding: 1px 2px 3px 4px;
}
a {
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
}
a { margin: 1px; }
declaration-block-no-shorthand-property-overrides
/* ✗ bad */
a {
padding-left: 10px;
padding: 20px;
}
/* ✓ good */
a {
padding: 20px;
padding-left: 10px;
}
number-leading-zero, number-no-trailing-zeros
/* ✓ bad */
a { top: 3.2450908px; }
/* ✓ good */
a { top: 3.245px; }
/* ✗ bad */
a { color: #000; }
a { color: #ffffffaa; }
/* ✓ good */
a { color: black; }
a { color: #fffa; }
function-linear-gradient-no-nonstandard-direction
/* ✗ bad */
.foo { background: linear-gradient(top,white,black); }
.foo { background: linear-gradient(45,white,black); }
.foo { background: linear-gradient(to top top,white,black); }
/* ✓ good */
.foo { background: linear-gradient(to top,white,black); }
.foo { background: linear-gradient(45deg,white,black); }
.foo { background: linear-gradient(1.57rad,white,black); }
comment-whitespace-inside comment-no-empty
/* ✗ bad */
/**/
/*
*/
/*comment*/
/* ✓ good */
/* comment */
/*
* Multi-line Comment
**/
no-invalid-double-slash-comments
/* ✗ bad */
a {
// color: pink;
}
/* ✓ good */
a {
/* color: pink; */
}
declaration-block-no-duplicate-properties, no-duplicate-selectors, no-duplicate-at-import-rules, font-family-no-duplicate-names
/* ✗ bad */
a {
color: pink;
color: orange;
font-family: 'Times', Times, serif;
}
p {
font-size: 16px;
font-weight: 400;
font-size: 1rem;
}
@import 'a.css';
@import 'a.css';
/* ✓ good */
a {
color: pink;
font-family: Times, serif;
}
p {
font-size: 16px;
font-size: 1rem;
font-weight: 400;
}
@import 'a.css';
at-rule-no-unknown, selector-pseudo-class-no-unknown, selector-pseudo-element-no-unknown, selector-type-no-unknown, property-no-unknown, unit-no-unknown, color-no-invalid-hex, media-feature-name-no-unknown, no-unknown-animations
/* ✗ bad */
@unknow {}
@media screen and (unknown) {}
a:unknown {
colr: blue;
background: #y3;
width: 10pixels;
}
a::element {}
tag {}
a {
width: 10pixels;
}
a {
color: #00;
}
a { animation-name: fancy-slide; }
/* ✓ good */
@charset "utf-8";
@media (min-width: 700px) {}
a:hover {
color: blue;
background: white;
width: 10px;
}
a::before {}
input {}
a {
width: 10px;
}
a {
color: #00;
}
a { animation-name: fancy-slide; }
@keyframes fancy-slide {}
/* ✗ bad */
a {
content: "first
second";
}
/* ✓ good */
a {
content: "first\\nsecond";
}
font-family-no-missing-generic-family-keyword
/* ✗ bad */
a {
font-family: Helvetica, Arial, Verdana, Tahoma;
}
/* ✓ good */
a {
font-family: Helvetica, Arial, Verdana, Tahoma, serif;
}
keyframe-declaration-no-important
/* ✗ bad */
@keyframes important1 {
from {
margin-top: 50px;
}
to {
margin-top: 100px !important;
}
}
/* ✓ good */
@keyframes important1 {
from {
margin-top: 50px;
}
to {
margin-top: 100px;
}
}