Skip to content

A Stylelint plugin to enforce the use of logical CSS properties, directional keywords and units.

License

Notifications You must be signed in to change notification settings

yuschick/stylelint-plugin-logical-css

Repository files navigation

Stylelint Plugin - Logical CSS Logo Dark

Stylelint Plugin Logical CSS License Stylelint Plugin Logical CSS Latest NPM Version Stylelint Plugin Logical CSS Main Workflow Status Stylelint Plugin Logical CSS NPM Downloads

A Stylelint plugin to enforce the use of logical CSS properties, values and units for adaptive, i18n-first styles.

Table of Contents

Getting Started | Quickstart | Plugin Configs | Plugin Rules | Troubleshooting

Getting Started

Important

The plugin requires Stylelint v14.0.0 or greater.

To get started using the plugin, it must first be installed.

npm i stylelint-plugin-logical-css --save-dev
yarn add stylelint-plugin-logical-css --dev

With the plugin installed, it must be added to the plugins array of your Stylelint config.

{
  "plugins": ["stylelint-plugin-logical-css"],
}

After adding the plugin to the configuration file, you now have access to the various rules and options it provides.

Quickstart

After installation, add this to your .stylelintrc.json:

{
  "plugins": ["stylelint-plugin-logical-css"],
  "extends": ["stylelint-plugin-logical-css/configs/recommended"]
}

Logical CSS Configs

For quick setup, the plugin provides preset configurations that enable commonly used rules.

Recommended

The recommended preset enables core logical CSS rules with sensible defaults, suitable for most projects.

Usage:

{
  "extends": ["stylelint-plugin-logical-css/configs/recommended"]
}

Equivalent to:

{
  "plugins": ["stylelint-plugin-logical-css"],
  "rules": {
    "logical-css/require-logical-keywords": [
      true,
      { "ignore": ["caption-side", "offset-anchor", "offset-position"], "severity": "error" },
    ],
    "logical-css/require-logical-properties": [true, { "severity": "error" }],
    "logical-css/require-logical-units": [true, { "severity": "error" }],
  },
}

Logical CSS Rules

The plugin provides multiple rules that can be toggled on and off as needed.

  1. Require Logical Keywords
  2. Require Logical Properties
  3. Require Logical Units

Require Logical Keywords

Physical CSS directional keywords like left, right, top, bottom, horizontal, and vertical reference absolute directions that don't adapt to writing modes or text direction. Logical keywords like start, end, inline-start, block-end, inline, and block automatically adjust based on the document's writing mode, supporting internationalization and adaptive layouts.

Enable this rule to: Enforce the use of logical CSS directional keywords (start, end, inline-start, block-end, inline, block, etc.) over their physical equivalents (left, right, top, bottom, horizontal, vertical) in property values, ensuring your styles adapt properly to different writing modes and text directions.

{
  "rules": {
    "logical-css/require-logical-keywords": true,
  }
}

Require Logical Keywords Options

type Severity = 'error' |Β 'warning';

interface SecondaryOptions {
  fix?: boolean;
  ignore?: PhysicalKeywordProperty[],
  severity?: Severity 
}
{
  "rules": {
    "logical-css/require-logical-keywords": [true, { 
      "fix": true,
      "ignore": ["caption-side", "offset-anchor"],
      "severity": "error",
    }]
  }
}

Require Logical Keywords Map

The following table shows how physical CSS directional keywords are mapped to their logical equivalents. When this rule detects a physical keyword, it will suggest (or automatically fix, if enabled) the corresponding logical keyword.

πŸš€ View Physical to Logical Keyword Mappings
Property Physical Keyword(s) Logical Keyword(s)
box-orient horizontal, vertical inline-axis, block-axis
caption-side top, bottom, left, right block-start, block-end, inline-start, inline-end
clear left, right inline-start, inline-end
float left, right inline-start, inline-end
offset-anchor top, bottom, left, right block-start, block-end, inline-start, inline-end
offset-position top, bottom, left, right block-start, block-end, inline-start, inline-end
resize horizontal, vertical inline, block
text-align left, right start, end
text-align-last left, right start, end

Require Logical Keywords Examples

βœ… Passing Examples
.text {
  text-align: start;
  text-align-last: end;
}

.layout {
  float: inline-start;
  clear: inline-end;
}

.box {
  resize: inline;
}

.table {
  caption-side: block-start;
}

.legacy {
  box-orient: inline-axis;
}

.positioned {
  offset-anchor: block-end inline-start;
  offset-position: block-start inline-end;
}
❌ Failing Examples
.text {
  text-align: left;
  text-align-last: right;
}

.layout {
  float: left;
  clear: right;
}

.box {
  resize: horizontal;
}

.table {
  caption-side: top;
}

.legacy {
  box-orient: vertical;
}

.positioned {
  offset-anchor: bottom left;
  offset-position: top right;
}

Require Logical Properties

Physical CSS properties like width, height, left, and margin-top reference absolute dimensions and directions that don't adapt to writing modes or text direction. Logical properties like inline-size, block-size, inset-inline-start, and margin-block-start automatically adjust based on the document's writing mode, supporting internationalization and adaptive layouts.

Enable this rule to: Enforce the use of logical CSS properties (inline-size, block-size, margin-inline, padding-block, etc.) over their physical equivalents (width, height, margin-left, padding-top, etc.), ensuring your styles adapt properly to different writing modes and text directions.

{
  "rules": {
    "logical-css/require-logical-properties": true,
  }
}

Require Logical Properties Options

Configuration: By default, this rule validates all CSS declarations for any use of physical properties (width, height, top, left, margin-left, padding-top, etc.). Use the rule options to exclude specific physical properties from validation, automate physical-to-logical property fixing, or adjust the severity level as needed.

type Severity = 'error' |Β 'warning';

interface SecondaryOptions {
  fix?: boolean;
  ignore?: PhysicalProperty[],
  severity?: Severity 
}
{
  "rules": {
    "logical-css/require-logical-properties": [true, { 
      "fix": true,
      "ignore": ["height", "scroll-margin-bottom", "width"],
      "severity": "error",
    }]
  }
}

Require Logical Properties Map

The following table shows how physical CSS properties are mapped to their logical equivalents. When this rule detects a physical property, it will suggest (or automatically fix, if enabled) the corresponding logical property.

πŸš€ View Physical to Logical Properties Mappings
Physical Property Logical Property Description
border-bottom border-block-end Bottom border β†’ Block end border
border-bottom-color border-block-end-color Bottom border color β†’ Block end border color
border-bottom-left-radius border-end-start-radius Bottom-left radius β†’ End-start radius
border-bottom-right-radius border-end-end-radius Bottom-right radius β†’ End-end radius
border-bottom-style border-block-end-style Bottom border style β†’ Block end border style
border-bottom-width border-block-end-width Bottom border width β†’ Block end border width
border-left border-inline-start Left border β†’ Inline start border
border-left-color border-inline-start-color Left border color β†’ Inline start border color
border-left-style border-inline-start-style Left border style β†’ Inline start border style
border-left-width border-inline-start-width Left border width β†’ Inline start border width
border-right border-inline-end Right border β†’ Inline end border
border-right-color border-inline-end-color Right border color β†’ Inline end border color
border-right-style border-inline-end-style Right border style β†’ Inline end border style
border-right-width border-inline-end-width Right border width β†’ Inline end border width
border-top border-block-start Top border β†’ Block start border
border-top-color border-block-start-color Top border color β†’ Block start border color
border-top-left-radius border-start-start-radius Top-left radius β†’ Start-start radius
border-top-right-radius border-start-end-radius Top-right radius β†’ Start-end radius
border-top-style border-block-start-style Top border style β†’ Block start border style
border-top-width border-block-start-width Top border width β†’ Block start border width
bottom inset-block-end Bottom position β†’ Block end position
contain-intrinsic-height contain-intrinsic-block-size Intrinsic height β†’ Intrinsic block size
contain-intrinsic-width contain-intrinsic-inline-size Intrinsic width β†’ Intrinsic inline size
height block-size Height β†’ Block size
left inset-inline-start Left position β†’ Inline start position
margin-bottom margin-block-end Bottom margin β†’ Block end margin
margin-left margin-inline-start Left margin β†’ Inline start margin
margin-right margin-inline-end Right margin β†’ Inline end margin
margin-top margin-block-start Top margin β†’ Block start margin
max-height max-block-size Maximum height β†’ Maximum block size
max-width max-inline-size Maximum width β†’ Maximum inline size
min-height min-block-size Minimum height β†’ Minimum block size
min-width min-inline-size Minimum width β†’ Minimum inline size
overflow-x overflow-inline Horizontal overflow β†’ Inline overflow
overflow-y overflow-block Vertical overflow β†’ Block overflow
overscroll-behavior-x overscroll-behavior-inline Horizontal overscroll β†’ Inline overscroll
overscroll-behavior-y overscroll-behavior-block Vertical overscroll β†’ Block overscroll
padding-bottom padding-block-end Bottom padding β†’ Block end padding
padding-left padding-inline-start Left padding β†’ Inline start padding
padding-right padding-inline-end Right padding β†’ Inline end padding
padding-top padding-block-start Top padding β†’ Block start padding
right inset-inline-end Right position β†’ Inline end position
scroll-margin-bottom scroll-margin-block-end Bottom scroll margin β†’ Block end scroll margin
scroll-margin-left scroll-margin-inline-start Left scroll margin β†’ Inline start scroll margin
scroll-margin-right scroll-margin-inline-end Right scroll margin β†’ Inline end scroll margin
scroll-margin-top scroll-margin-block-start Top scroll margin β†’ Block start scroll margin
scroll-padding-bottom scroll-padding-block-end Bottom scroll padding β†’ Block end scroll padding
scroll-padding-left scroll-padding-inline-start Left scroll padding β†’ Inline start scroll padding
scroll-padding-right scroll-padding-inline-end Right scroll padding β†’ Inline end scroll padding
scroll-padding-top scroll-padding-block-start Top scroll padding β†’ Block start scroll padding
top inset-block-start Top position β†’ Block start position
width inline-size Width β†’ Inline size

Require Logical Properties Examples

βœ… Passing Examples
.element {
  inline-size: 100%;
  block-size: 50vh;
}

.box {
  margin-block-start: 1rem;
  margin-inline: 2rem;
  padding-block: 10px;
  padding-inline-end: 20px;
}

.positioned {
  inset-inline-start: 0;
  inset-block-end: 10px;
}

.borders {
  border-inline-start: 1px solid black;
  border-block-end-color: red;
  border-start-start-radius: 8px;
}
❌ Failing Examples
.element {
  width: 100%;
  height: 50vh;
}

.box {
  margin-top: 1rem;
  margin-left: 2rem;
  margin-right: 2rem;
  padding-top: 10px;
  padding-bottom: 10px;
  padding-right: 20px;
}

.positioned {
  left: 0;
  bottom: 10px;
}

.borders {
  border-left: 1px solid black;
  border-bottom-color: red;
  border-top-left-radius: 8px;
}

Require Logical Units

Note

Read about current browser support for logical CSS units.

Physical CSS units like vh (viewport height) and vw (viewport width) reference absolute dimensions that don't adapt to writing modes or text direction. Logical units like vb (viewport block) and vi (viewport inline) automatically adjust based on the document's writing mode, supporting internationalization and adaptive layouts.

Enable this rule to: Enforce the use of logical CSS units (vb, vi, cqb, cqi, etc.) over their physical equivalents (vh, vw, cqh, cqw, etc.), ensuring your styles adapt properly to different writing modes and text directions.

{
  "rules": {
    "logical-css/require-logical-units": true,
  }
}

Require Logical Units Options

Configuration: By default, this rule validates all CSS properties for any use of physical units (vh, vw, dvh, dvw, lvh, lvw, svh, svw, cqh, cqw). Use the rule options to exclude specific physical units from validation, automate physical-to-logical unit fixing, or adjust the severity level as needed.

type Severity = 'error' |Β 'warning';

interface SecondaryOptions {
  fix?: boolean;
  ignore?: PhysicalUnit[],
  severity?: Severity 
}
{
  "rules": {
    "logical-css/require-logical-units": [true, { 
      "fix": true,
      "ignore": ["vh", "dvw"],
      "severity": "error",
    }]
  }
}

Require Logical Units Map

The following table shows how physical CSS units are mapped to their logical equivalents. When this rule detects a physical unit, it will suggest (or automatically fix, if enabled) the corresponding logical unit.

πŸš€ View Physical to Logical Unit Mappings
Physical Unit Logical Unit Description
vh vb Viewport height β†’ Viewport block
vw vi Viewport width β†’ Viewport inline
dvh dvb Dynamic viewport height β†’ Dynamic viewport block
dvw dvi Dynamic viewport width β†’ Dynamic viewport inline
lvh lvb Large viewport height β†’ Large viewport block
lvw lvi Large viewport width β†’ Large viewport inline
svh svb Small viewport height β†’ Small viewport block
svw svi Small viewport width β†’ Small viewport inline
cqh cqb Container query height β†’ Container query block
cqw cqi Container query width β†’ Container query inline

Require Logical Units Examples

βœ… Passing Examples
.element {
  block-size: 100vb;
  inline-size: 80vi;
}

.card {
  max-block-size: 50cqb;
  max-inline-size: 100cqi;
}

.hero {
  min-block-size: 100dvb;
  inline-size: min(80vi, 100%);
}

.responsive {
  inline-size: clamp(20vi, 50%, 80vi);
}
❌ Failing Examples
.element {
  height: 100vh;
  width: 80vw;
}

.card {
  max-height: 50cqh;
  max-width: 100cqw;
}

.hero {
  min-height: 100dvh;
  width: min(80vw, 100%);
}

.responsive {
  width: clamp(20vw, 50%, 80vw);
}

.partial {
  width: 50.5vw;
}

Troubleshooting

Ignoring Specific Patterns

As an escape hatch, use Stylelint's built-in disable comments to bypass specific rules:

div {
  /* stylelint-disable-next-line logical-css/require-logical-properties */
  width: 100%;
}

About

A Stylelint plugin to enforce the use of logical CSS properties, directional keywords and units.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Contributors 7