From b5981dec8a2cd0956a1e9e04cb164775b3d22744 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 05:42:32 +0000 Subject: [PATCH 1/3] Update dependency stylelint-config-cloudfour to v12 --- package-lock.json | 10 ++++++---- package.json | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index af0e6c68e..6b3f4532b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,7 @@ "storybook": "10.6.1", "style-dictionary": "5.6.1", "stylelint": "17.16.0", - "stylelint-config-cloudfour": "11.0.0", + "stylelint-config-cloudfour": "12.0.0", "stylelint-scss": "7.3.0", "svgo": "4.1.0", "terser": "5.51.2", @@ -20341,11 +20341,13 @@ } }, "node_modules/stylelint-config-cloudfour": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-cloudfour/-/stylelint-config-cloudfour-11.0.0.tgz", - "integrity": "sha512-CPB4a/qkdP4+k/exJ/aoqNmrvEqlMcly9mtdSb8Xi6PC8vOVjRvTbm3ijahDTYp3H81FsnJmYWVQ3l7tr5tXTg==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-cloudfour/-/stylelint-config-cloudfour-12.0.0.tgz", + "integrity": "sha512-ITbdXoMiENSsfftNMA8R2oShnAGtfk6dF0IfGJuKKHAk5FSjHU6Y7T82nGeffTuMJkdVIREmuO5sWmKRttTMlw==", "dev": true, + "license": "MIT", "dependencies": { + "stylelint-config-standard": "40.0.0", "stylelint-config-standard-scss": "17.0.0", "stylelint-declaration-block-no-ignored-properties": "3.0.0", "stylelint-high-performance-animation": "2.0.0", diff --git a/package.json b/package.json index 58e0425cd..f200ef375 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "storybook": "10.6.1", "style-dictionary": "5.6.1", "stylelint": "17.16.0", - "stylelint-config-cloudfour": "11.0.0", + "stylelint-config-cloudfour": "12.0.0", "stylelint-scss": "7.3.0", "svgo": "4.1.0", "terser": "5.51.2", From bcd6a7196b930a444e53162c3e9568100b6021b0 Mon Sep 17 00:00:00 2001 From: Scott Vandehey Date: Wed, 14 Oct 2026 10:03:58 -0700 Subject: [PATCH 2/3] Align Stylelint config with stylelint-config-cloudfour v12 v12 disables the stylelint-scss rules that conflict with Prettier and enables unit-layout-mappings itself, so the local copies are redundant. The local property-layout-mappings and value-keyword-layout-mappings settings replace the shared config's options, which dropped its overflow-x/overflow-y and offset-anchor/offset-position exceptions. Repeat those alongside the repo's own exceptions. --- .stylelintrc.js | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/.stylelintrc.js b/.stylelintrc.js index 4058fa224..e2904ff6a 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -1,26 +1,6 @@ module.exports = { extends: ['stylelint-config-cloudfour'], rules: { - // Disable stylelint-scss rules that conflict with Prettier. - // - // stylelint 15 deprecated its own stylistic rules and 16 removed them, which is - // why `stylelint-config-prettier` is gone -- it has nothing left to turn off and - // is unusable past stylelint 14. That retirement did not extend to stylelint-scss, - // which still ships and enables every one of these, so they still have to be - // disabled by hand. - 'scss/at-else-closing-brace-newline-after': null, - 'scss/at-else-closing-brace-space-after': null, - 'scss/at-else-empty-line-before': null, - 'scss/at-else-if-parentheses-space-before': null, - 'scss/at-function-parentheses-space-before': null, - 'scss/at-if-closing-brace-newline-after': null, - 'scss/at-if-closing-brace-space-after': null, - 'scss/at-mixin-parentheses-space-before': null, - 'scss/dollar-variable-colon-space-after': null, - 'scss/dollar-variable-colon-space-before': null, - 'scss/operator-no-newline-after': null, - 'scss/operator-no-newline-before': null, - 'scss/operator-no-unspaced': null, /** * 1. separating grid-template-rows and grid-template-columns * improves readability @@ -51,20 +31,31 @@ module.exports = { true, { ignoreMediaFeatureNames: ['breakpoint'] }, ], - // Prefer flow-relative (logical) properties, units, and keywords. + // The shared config enables these, but setting a rule replaces its + // options, so the shared config's ignored properties are repeated here. 'property-layout-mappings': [ 'flow-relative', { - // Until Safari 15 adoption is higher - ignoreProperties: [/^border-.+-radius$/v], + ignoreProperties: [ + // Until Safari 15 adoption is higher + /^border-.+-radius$/v, + // Shared config: overflow-inline and overflow-block need Safari 26 + 'overflow-x', + 'overflow-y', + ], }, ], - 'unit-layout-mappings': 'flow-relative', 'value-keyword-layout-mappings': [ 'flow-relative', { - // Until Safari 15 adoption is higher - ignoreProperties: ['clear', 'float'], + ignoreProperties: [ + // Until Safari 15 adoption is higher + 'clear', + 'float', + // Shared config: browsers don't support logical keywords in these yet + 'offset-anchor', + 'offset-position', + ], }, ], }, From 8b1911a94f454a850b76ec049fdf19b715bf169a Mon Sep 17 00:00:00 2001 From: Scott Vandehey Date: Wed, 14 Oct 2026 10:11:30 -0700 Subject: [PATCH 3/3] Use the shared config's logical property rules The local property-layout-mappings and value-keyword-layout-mappings settings only added exceptions for physical border radii and floats, pending Safari 15 support. Every browser we target now supports the logical versions, so drop the local rules and use the shared config's. Converted with `stylelint --fix`, which also removed the physical float fallbacks from the float utilities. Also remove a disable comment for the stylelint-use-logical-spec plugin, which #2522 replaced. --- .changeset/brave-corners-float.md | 5 ++++ .stylelintrc.js | 27 ------------------- src/components/alert/alert.scss | 4 +-- .../calendar-date/calendar-date.scss | 8 +++--- src/design/demo/favicon-tabs.scss | 4 +-- src/mixins/_toggle-input.scss | 5 +--- src/objects/hype-group/hype-group.scss | 2 +- src/objects/input-group/input-group.scss | 8 +++--- src/utilities/float/float.mdx | 2 +- src/utilities/float/float.scss | 2 -- src/vendor/wordpress/styles/_core-blocks.scss | 4 +-- .../wordpress/styles/_jetpack-blocks.scss | 6 ++--- 12 files changed, 25 insertions(+), 52 deletions(-) create mode 100644 .changeset/brave-corners-float.md diff --git a/.changeset/brave-corners-float.md b/.changeset/brave-corners-float.md new file mode 100644 index 000000000..413438332 --- /dev/null +++ b/.changeset/brave-corners-float.md @@ -0,0 +1,5 @@ +--- +'@cloudfour/patterns': patch +--- + +Use logical CSS for corner radii and floats: `border-start-start-radius` and friends instead of `border-top-left-radius` in the Alert, Calendar Date and Input Group patterns, and `float`/`clear` `inline-start`/`inline-end` instead of `left`/`right` in Hype Group and the WordPress image and Jetpack contact form styles. Remove the physical `float` fallbacks from the float utilities. diff --git a/.stylelintrc.js b/.stylelintrc.js index e2904ff6a..3a9b7a51d 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -31,32 +31,5 @@ module.exports = { true, { ignoreMediaFeatureNames: ['breakpoint'] }, ], - // The shared config enables these, but setting a rule replaces its - // options, so the shared config's ignored properties are repeated here. - 'property-layout-mappings': [ - 'flow-relative', - { - ignoreProperties: [ - // Until Safari 15 adoption is higher - /^border-.+-radius$/v, - // Shared config: overflow-inline and overflow-block need Safari 26 - 'overflow-x', - 'overflow-y', - ], - }, - ], - 'value-keyword-layout-mappings': [ - 'flow-relative', - { - ignoreProperties: [ - // Until Safari 15 adoption is higher - 'clear', - 'float', - // Shared config: browsers don't support logical keywords in these yet - 'offset-anchor', - 'offset-position', - ], - }, - ], }, }; diff --git a/src/components/alert/alert.scss b/src/components/alert/alert.scss index 23282e68d..2411be1af 100644 --- a/src/components/alert/alert.scss +++ b/src/components/alert/alert.scss @@ -96,8 +96,8 @@ --icon-size: #{size.$icon-medium}; align-items: center; background-color: var(--theme-color-background-icon); - border-bottom-left-radius: size.$border-radius-medium; - border-top-left-radius: size.$border-radius-medium; + border-end-start-radius: size.$border-radius-medium; + border-start-start-radius: size.$border-radius-medium; color: var(--theme-color-icon); display: flex; grid-area: icon; diff --git a/src/components/calendar-date/calendar-date.scss b/src/components/calendar-date/calendar-date.scss index 625e375c9..ddde1200f 100644 --- a/src/components/calendar-date/calendar-date.scss +++ b/src/components/calendar-date/calendar-date.scss @@ -44,8 +44,8 @@ $radius: size.$border-radius-medium; block-size: ms.step(3); border: $edge-size solid color.$base-gray-darker; /* 1 */ border-block-end-width: 0; - border-top-left-radius: $radius; - border-top-right-radius: $radius; + border-start-end-radius: $radius; + border-start-start-radius: $radius; color: color.$text-light-emphasis; display: flex; flex: none; @@ -91,8 +91,8 @@ $radius: size.$border-radius-medium; background-color: color.$text-light-emphasis; border: $edge-size solid var(--theme-color-border-calendar-date); border-block-start-width: 0; - border-bottom-left-radius: $radius; - border-bottom-right-radius: $radius; + border-end-end-radius: $radius; + border-end-start-radius: $radius; color: color.$text-dark; display: flex; flex: 1; diff --git a/src/design/demo/favicon-tabs.scss b/src/design/demo/favicon-tabs.scss index 4d48134d0..73919af0a 100644 --- a/src/design/demo/favicon-tabs.scss +++ b/src/design/demo/favicon-tabs.scss @@ -18,8 +18,8 @@ li { align-items: center; block-size: 36px; - border-top-left-radius: size.$border-radius-medium; - border-top-right-radius: size.$border-radius-medium; + border-start-end-radius: size.$border-radius-medium; + border-start-start-radius: size.$border-radius-medium; display: flex; flex: 1; max-inline-size: 220px; diff --git a/src/mixins/_toggle-input.scss b/src/mixins/_toggle-input.scss index d0aa43db0..61c1921c2 100644 --- a/src/mixins/_toggle-input.scss +++ b/src/mixins/_toggle-input.scss @@ -165,14 +165,11 @@ @include base-hover; } - /// 1. Our linter is getting confused by the Sass expression and trying to - /// split this into multiple lines. &::after { @include base-inner-pseudo-default; background-color: currentColor; border-radius: inherit; - // stylelint-disable-next-line liberty/use-logical-spec - inset: size.$edge-control * 2; // 1 + inset: size.$edge-control * 2; } &:checked { diff --git a/src/objects/hype-group/hype-group.scss b/src/objects/hype-group/hype-group.scss index 2bd20e07f..bcab23b1b 100644 --- a/src/objects/hype-group/hype-group.scss +++ b/src/objects/hype-group/hype-group.scss @@ -116,7 +116,7 @@ $breakpoint-wide: breakpoint.$m + 5em; @media (width < $breakpoint-wide) { aspect-ratio: 2/3; // 1 - float: right; + float: inline-end; inline-size: calc(50% - #{size.$spacing-gap-inline-small}); // 2 margin: size.$spacing-gap-inline-small; margin-inline-end: 0; diff --git a/src/objects/input-group/input-group.scss b/src/objects/input-group/input-group.scss index 12272ee35..997e033ec 100644 --- a/src/objects/input-group/input-group.scss +++ b/src/objects/input-group/input-group.scss @@ -12,13 +12,13 @@ } > :not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-end-start-radius: 0; + border-start-start-radius: 0; } > :not(:last-child) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; + border-end-end-radius: 0; + border-start-end-radius: 0; } > * + * { diff --git a/src/utilities/float/float.mdx b/src/utilities/float/float.mdx index 948e3fd45..d05ead87e 100644 --- a/src/utilities/float/float.mdx +++ b/src/utilities/float/float.mdx @@ -10,7 +10,7 @@ Utilities for controlling the float of an element. Useful for responsively arran ## Flow-Relative Properties -These utilities use flow-relative values instead of specific directions [in supported browsers](https://caniuse.com/mdn-css_properties_float_flow_relative_values) to simplify potential localization projects. +These utilities use [flow-relative values](https://caniuse.com/mdn-css_properties_float_flow_relative_values) instead of specific directions to simplify potential localization projects. The following table maps the traditional directional property for `direction: ltr` and `writing-mode: horizontal-tb` to its equivalent flow-relative property: diff --git a/src/utilities/float/float.scss b/src/utilities/float/float.scss index 24e7aec99..212a8241d 100644 --- a/src/utilities/float/float.scss +++ b/src/utilities/float/float.scss @@ -4,12 +4,10 @@ // breakpoint suffixes. @mixin _float-utilities($suffix: '') { .u-float-inline-start#{$suffix} { - float: left; float: inline-start; } .u-float-inline-end#{$suffix} { - float: right; float: inline-end; } diff --git a/src/vendor/wordpress/styles/_core-blocks.scss b/src/vendor/wordpress/styles/_core-blocks.scss index 263758962..e8699dd39 100644 --- a/src/vendor/wordpress/styles/_core-blocks.scss +++ b/src/vendor/wordpress/styles/_core-blocks.scss @@ -477,14 +477,14 @@ figure.wp-block-image { &.alignleft { @media (width >= breakpoint.$m) { - float: left; + float: inline-start; margin-inline-end: size.$rhythm-generous; } } &.alignright { @media (width >= breakpoint.$m) { - float: right; + float: inline-end; margin-inline-start: size.$rhythm-generous; } } diff --git a/src/vendor/wordpress/styles/_jetpack-blocks.scss b/src/vendor/wordpress/styles/_jetpack-blocks.scss index 0821f3893..b26458586 100644 --- a/src/vendor/wordpress/styles/_jetpack-blocks.scss +++ b/src/vendor/wordpress/styles/_jetpack-blocks.scss @@ -154,7 +154,7 @@ /// too much to enforce consistent columns. .field-name, .field-value { - float: left; + float: inline-start; } /// 1. Break onto a new line with each field name. @@ -163,7 +163,7 @@ /// affordances to make the values distinct. /// 3. Add a bit of space between names and values. .field-name { - clear: left; // 1 + clear: inline-start; // 1 font-weight: font-weight.$medium; // 2 margin-inline-end: 1ch; // 3 @@ -180,7 +180,7 @@ /// Empty field values need to clear floats to maintain margin. &:empty { - clear: left; + clear: inline-start; float: none; /// If the browser supports `:has()`, we can hide the field value entirely