API ReferencePluginsESLint Plugin

Optional rules

recommended reports defects. These three do something else: they take away the room for one, at the cost of narrowing how you are allowed to write. None of them is on by default.

What they are for

Specificity settles every pair where one property contains another — a shorthand and its longhand, an axis and an edge. What it cannot settle is a pair where neither side contains the other, and there are exactly two shapes of those:

ExampleLeft to
One property under two namespaddingTop and paddingBlockStartthe order they are written
Two shorthands that crossborderTop and borderBlockWidththe order they are written

no-order-dependent-overlap, which recommended turns on, warns when such a pair meets on one element. The rules below stop the pair from existing.

import plumeria from '@plumeria/eslint-plugin';

export default [
  plumeria.configs.recommended,
  {
    rules: {
      '@plumeria/expand-border-shorthands': 'warn',
      '@plumeria/no-physical-properties': 'warn',
    },
  },
];

Both are fixable or offer a rename, so adopting them on an existing codebase is mostly a matter of running the fixer once and reading the leftovers.

expand-border-shorthands

border, borderBlock, borderInline and the eight edge forms each set a width, a style and a color at once. Every pair that specificity cannot rank contains one of those eleven, so writing out the three declarations they stand for is what removes the shape.

borderTop: '1px solid red'
// fixes to
borderTopWidth: '1px',
borderTopStyle: 'solid',
borderTopColor: 'red'

borderTop and borderBlockWidth cross: the first sets three values on one edge, the second sets one value on two edges, and they meet on border-top-width without either containing the other. borderTopWidth and borderBlockWidth do not cross — the first is contained by the second, and the depth of each decides the winner.

A shorthand resets whatever it omits, so the expansion writes the initial value of every component you left out:

borderBlock: 'solid'
// fixes to
borderBlockWidth: 'medium',
borderBlockStyle: 'solid',
borderBlockColor: 'currentcolor'

A value the rule cannot split — var(--edge), inherit, a reference — is reported without a fix. Write the three declarations yourself, or the ones the fixer expanded elsewhere will outrank it.

no-physical-properties / no-logical-properties

A property that carries both a logical and a physical name can be written twice under two spellings. Pick one spelling and the pair cannot occur.

'@plumeria/no-physical-properties': 'warn'
// paddingLeft → rename to paddingInlineStart

'@plumeria/no-logical-properties': 'warn'
// paddingInlineStart → rename to paddingLeft

Turning both on is contradictory. no-physical-properties is the direction that keeps a document working in another writing mode or another direction, which is what the logical names exist for.

Each accepts { sizes }, false by default:

'@plumeria/no-physical-properties': ['warn', { sizes: true }]

Off, the rule covers the edges — paddingLeft, marginTop, top, borderTopColor. On, it also covers width, height, their min and max forms, and overflow-x and overflow-y. An edge is what a direction reverses; a size is the same box either way, so renaming it buys less and touches far more code.

Renaming is offered as a suggestion rather than a fix. In a vertical writing mode the two spellings are two different edges, so the rewrite is a change of meaning that you should apply deliberately.

What is left

A shorthand with no single counterpart, such as borderBlockWidth, belongs to neither spelling and is never renamed. With expand-border-shorthands on, it no longer has anything to cross with.

Two conditions that can match at the same time — @media (min-width: 600px) and @media (min-width: 900px) — still resolve by the order they are written. That is deliberate: no depth can rank them, because whether one condition implies another is not decidable in general. no-order-dependent-overlap covers the part that is: where one query provably matches a subset of the other and the narrower one is written first, it says so and offers the swap.

On this page