A few years ago I was on a new project at work as the frontend engineer. In code reviews I would recommend reordering of CSS properties, as many of us have a preferred order. One of my teammates pointed out that she would never remember my order and thus wouldn’t likely follow it, so I should find a way to automate it.
Stylelint and Stylelint Order enter chatroom.
As I have become accustomed to over the years, most JavaScript engineers are very familiar with ESLint. If you aren’t, please go research and use it. It cleans up your code, makes it consistent, and helps when you are on a larger team than just you. But, frankly, it even helps when it is just you. JavaScript allows chaos. Semicolons are optional. ‘Nough said. What engineers often don’t even think about is linting their CSS. Many don’t consider CSS a “real language,” but that is a different conversation.
Stylelint is exactly what you would expect if you’ve worked with ESLint. I use the stylelint-config-standard to start. This handles most things. I turn off a few items. The biggest part of my config is the custom ordering of properties using stylelint-order.
As you can see below, I separate my properties into groups (eg. display, grid, dimensions). This means position: absolute;
is followed by top
, which just makes sense. width
and height
are right by each other. Alphabetical and other sorts work for different people for different reasons, but logically sorting by type of property just keeps me sane.
The nice thing about this is if your run Stylelint, it’ll throw warnings on all things out of order. But, you can run Stylelint with --fix
and it will reorder your properties for you.
I bring this with me on every project. The one below is from this very site. A couple days ago I got ESLint and Stylelint working against Astro— I’m used to using it in React projects. I then fixed over 400 linting issues and now feel a peace knowing my code is consistent.
/* You'll need the following packages: stylelint, stylelint-config-standard, stylelint-order */
{
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-order"
],
"rules": {
"length-zero-no-unit": [true, {"ignore": ["custom-properties"]}],
"property-no-vendor-prefix": null,
"custom-property-pattern": null,
"selector-class-pattern": null,
"selector-id-pattern": null,
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"order/properties-order": [
[
{
"groupName": "display",
"properties": [
"content",
"appearance",
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"flex",
"flex-direction",
"flex-basis",
"flex-flow",
"flex-grow",
"flex-shrink",
"flex-wrap",
"align-content",
"align-items",
"justify-content",
"justify-items"
]
},
{
"groupName": "grid",
"properties": [
"grid",
"grid-area",
"grid-template",
"grid-template-areas",
"grid-template-rows",
"grid-template-columns",
"grid-row",
"grid-row-start",
"grid-row-end",
"grid-column",
"grid-column-start",
"grid-column-end",
"grid-auto-rows",
"grid-auto-columns",
"grid-auto-flow",
"grid-gap",
"grid-row-gap",
"grid-column-gap",
"gap"
]
},
{
"groupName": "dimensions",
"properties": [
"width",
"max-width",
"min-width",
"height",
"max-height",
"min-height"
]
},
{
"groupName": "margin and padding",
"properties": [
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left"
]
},
{
"groupName": "border and background",
"properties": [
"box-sizing",
"border",
"border-top",
"border-right",
"border-bottom",
"border-left",
"border-width",
"border-radius",
"outline",
"box-shadow",
"background",
"background-color",
"background-image"
]
},
{
"groupName": "font",
"properties": [
"font",
"font-family",
"font-size",
"font-style",
"font-weight",
"line-height",
"color",
"text-decoration",
"font-smoothing"
]
}
],
{
"unspecified": "bottom"
}
]
}
}
View Gist on Github