Add safe alignment utilities (#14607)
Fixes #7929 and #12916 This PR adds [safe alignment utilities](https://www.stefanjudis.com/today-i-learned/safe-unsafe-alignment-in-css-flexbox/) to Tailwind 4. I opted to include them for every justify/align content/items/self property, but only for the `end` and `center` values. I know that it doesn't make sense for `start` (as the point of safe alignment is to fall back to `start` when it overflows), but I'm not sure about `space-between`, `space-around`, or other values. I certainly never encountered a situation where I needed `safe` with those.
This commit is contained in:
parent
1d2d50ee66
commit
ebfde316e1
5 changed files with 147 additions and 1 deletions
|
|
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- _Experimental_: Add `items-baseline-last` utility ([#12128](https://github.com/tailwindlabs/tailwindcss/pull/12128))
|
||||
- _Experimental_: Add `pointer-none`, `pointer-coarse`, and `pointer-fine` variant ([#16946](https://github.com/tailwindlabs/tailwindcss/pull/16946))
|
||||
- _Experimental_: Add `any-pointer-none`, `any-pointer-coarse`, and `any-pointer-fine` variants ([#16941](https://github.com/tailwindlabs/tailwindcss/pull/16941))
|
||||
- _Experimental_: Add safe alignment utilities ([#14607](https://github.com/tailwindlabs/tailwindcss/pull/14607))
|
||||
- _Experimental_: Add `user-valid` and `user-invalid` variants ([#12370](https://github.com/tailwindlabs/tailwindcss/pull/12370))
|
||||
- _Experimental_: Add `wrap-anywhere`, `wrap-break-word`, and `wrap-normal` utilities ([#12128](https://github.com/tailwindlabs/tailwindcss/pull/12128))
|
||||
- _Experimental_: Add `@source inline(…)` ([#17147](https://github.com/tailwindlabs/tailwindcss/pull/17147))
|
||||
|
|
|
|||
|
|
@ -3746,7 +3746,9 @@ exports[`getClassList 1`] = `
|
|||
"content-baseline",
|
||||
"content-between",
|
||||
"content-center",
|
||||
"content-center-safe",
|
||||
"content-end",
|
||||
"content-end-safe",
|
||||
"content-evenly",
|
||||
"content-none",
|
||||
"content-normal",
|
||||
|
|
@ -4877,24 +4879,32 @@ exports[`getClassList 1`] = `
|
|||
"items-baseline",
|
||||
"items-baseline-last",
|
||||
"items-center",
|
||||
"items-center-safe",
|
||||
"items-end",
|
||||
"items-end-safe",
|
||||
"items-start",
|
||||
"items-stretch",
|
||||
"justify-around",
|
||||
"justify-baseline",
|
||||
"justify-between",
|
||||
"justify-center",
|
||||
"justify-center-safe",
|
||||
"justify-end",
|
||||
"justify-end-safe",
|
||||
"justify-evenly",
|
||||
"justify-items-center",
|
||||
"justify-items-center-safe",
|
||||
"justify-items-end",
|
||||
"justify-items-end-safe",
|
||||
"justify-items-normal",
|
||||
"justify-items-start",
|
||||
"justify-items-stretch",
|
||||
"justify-normal",
|
||||
"justify-self-auto",
|
||||
"justify-self-center",
|
||||
"justify-self-center-safe",
|
||||
"justify-self-end",
|
||||
"justify-self-end-safe",
|
||||
"justify-self-start",
|
||||
"justify-self-stretch",
|
||||
"justify-start",
|
||||
|
|
@ -6005,18 +6015,24 @@ exports[`getClassList 1`] = `
|
|||
"place-content-baseline",
|
||||
"place-content-between",
|
||||
"place-content-center",
|
||||
"place-content-center-safe",
|
||||
"place-content-end",
|
||||
"place-content-end-safe",
|
||||
"place-content-evenly",
|
||||
"place-content-start",
|
||||
"place-content-stretch",
|
||||
"place-items-baseline",
|
||||
"place-items-center",
|
||||
"place-items-center-safe",
|
||||
"place-items-end",
|
||||
"place-items-end-safe",
|
||||
"place-items-start",
|
||||
"place-items-stretch",
|
||||
"place-self-auto",
|
||||
"place-self-center",
|
||||
"place-self-center-safe",
|
||||
"place-self-end",
|
||||
"place-self-end-safe",
|
||||
"place-self-start",
|
||||
"place-self-stretch",
|
||||
"placeholder-current",
|
||||
|
|
@ -7280,7 +7296,9 @@ exports[`getClassList 1`] = `
|
|||
"self-auto",
|
||||
"self-baseline",
|
||||
"self-center",
|
||||
"self-center-safe",
|
||||
"self-end",
|
||||
"self-end-safe",
|
||||
"self-start",
|
||||
"self-stretch",
|
||||
"sepia",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ export const enableBaselineLast = process.env.FEATURES_ENV !== 'stable'
|
|||
export const enableDetailsContent = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enableInvertedColors = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enablePointerVariants = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enableSafeAlignment = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enableScripting = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enableSourceInline = process.env.FEATURES_ENV !== 'stable'
|
||||
export const enableUserValid = process.env.FEATURES_ENV !== 'stable'
|
||||
|
|
|
|||
|
|
@ -7125,8 +7125,10 @@ test('place-content', async () => {
|
|||
expect(
|
||||
await run([
|
||||
'place-content-center',
|
||||
'place-content-center-safe',
|
||||
'place-content-start',
|
||||
'place-content-end',
|
||||
'place-content-end-safe',
|
||||
'place-content-between',
|
||||
'place-content-around',
|
||||
'place-content-evenly',
|
||||
|
|
@ -7150,10 +7152,18 @@ test('place-content', async () => {
|
|||
place-content: center;
|
||||
}
|
||||
|
||||
.place-content-center-safe {
|
||||
place-content: safe center;
|
||||
}
|
||||
|
||||
.place-content-end {
|
||||
place-content: end;
|
||||
}
|
||||
|
||||
.place-content-end-safe {
|
||||
place-content: safe end;
|
||||
}
|
||||
|
||||
.place-content-evenly {
|
||||
place-content: space-evenly;
|
||||
}
|
||||
|
|
@ -7194,7 +7204,9 @@ test('place-items', async () => {
|
|||
await run([
|
||||
'place-items-start',
|
||||
'place-items-end',
|
||||
'place-items-end-safe',
|
||||
'place-items-center',
|
||||
'place-items-center-safe',
|
||||
'place-items-baseline',
|
||||
'place-items-stretch',
|
||||
]),
|
||||
|
|
@ -7207,10 +7219,18 @@ test('place-items', async () => {
|
|||
place-items: center;
|
||||
}
|
||||
|
||||
.place-items-center-safe {
|
||||
place-items: safe center;
|
||||
}
|
||||
|
||||
.place-items-end {
|
||||
place-items: end;
|
||||
}
|
||||
|
||||
.place-items-end-safe {
|
||||
place-items: safe end;
|
||||
}
|
||||
|
||||
.place-items-start {
|
||||
place-items: start;
|
||||
}
|
||||
|
|
@ -7241,8 +7261,10 @@ test('align-content', async () => {
|
|||
await run([
|
||||
'content-normal',
|
||||
'content-center',
|
||||
'content-center-safe',
|
||||
'content-start',
|
||||
'content-end',
|
||||
'content-end-safe',
|
||||
'content-between',
|
||||
'content-around',
|
||||
'content-evenly',
|
||||
|
|
@ -7266,10 +7288,18 @@ test('align-content', async () => {
|
|||
align-content: center;
|
||||
}
|
||||
|
||||
.content-center-safe {
|
||||
align-content: safe center;
|
||||
}
|
||||
|
||||
.content-end {
|
||||
align-content: flex-end;
|
||||
}
|
||||
|
||||
.content-end-safe {
|
||||
align-content: safe flex-end;
|
||||
}
|
||||
|
||||
.content-evenly {
|
||||
align-content: space-evenly;
|
||||
}
|
||||
|
|
@ -7316,7 +7346,9 @@ test('items', async () => {
|
|||
await run([
|
||||
'items-start',
|
||||
'items-end',
|
||||
'items-end-safe',
|
||||
'items-center',
|
||||
'items-center-safe',
|
||||
'items-baseline',
|
||||
'items-baseline-last',
|
||||
'items-stretch',
|
||||
|
|
@ -7334,10 +7366,18 @@ test('items', async () => {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.items-center-safe {
|
||||
align-items: safe center;
|
||||
}
|
||||
|
||||
.items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.items-end-safe {
|
||||
align-items: safe flex-end;
|
||||
}
|
||||
|
||||
.items-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
|
@ -7371,7 +7411,9 @@ test('justify', async () => {
|
|||
'justify-normal',
|
||||
'justify-start',
|
||||
'justify-end',
|
||||
'justify-end-safe',
|
||||
'justify-center',
|
||||
'justify-center-safe',
|
||||
'justify-between',
|
||||
'justify-around',
|
||||
'justify-evenly',
|
||||
|
|
@ -7390,10 +7432,18 @@ test('justify', async () => {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-center-safe {
|
||||
justify-content: safe center;
|
||||
}
|
||||
|
||||
.justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.justify-end-safe {
|
||||
justify-content: safe flex-end;
|
||||
}
|
||||
|
||||
.justify-evenly {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
|
@ -7438,7 +7488,9 @@ test('justify-items', async () => {
|
|||
await run([
|
||||
'justify-items-start',
|
||||
'justify-items-end',
|
||||
'justify-items-end-safe',
|
||||
'justify-items-center',
|
||||
'justify-items-center-safe',
|
||||
'justify-items-stretch',
|
||||
]),
|
||||
).toMatchInlineSnapshot(`
|
||||
|
|
@ -7446,10 +7498,18 @@ test('justify-items', async () => {
|
|||
justify-items: center;
|
||||
}
|
||||
|
||||
.justify-items-center-safe {
|
||||
justify-items: safe center;
|
||||
}
|
||||
|
||||
.justify-items-end {
|
||||
justify-items: end;
|
||||
}
|
||||
|
||||
.justify-items-end-safe {
|
||||
justify-items: safe end;
|
||||
}
|
||||
|
||||
.justify-items-start {
|
||||
justify-items: start;
|
||||
}
|
||||
|
|
@ -8298,7 +8358,9 @@ test('place-self', async () => {
|
|||
'place-self-auto',
|
||||
'place-self-start',
|
||||
'place-self-end',
|
||||
'place-self-end-safe',
|
||||
'place-self-center',
|
||||
'place-self-center-safe',
|
||||
'place-self-stretch',
|
||||
]),
|
||||
).toMatchInlineSnapshot(`
|
||||
|
|
@ -8310,10 +8372,18 @@ test('place-self', async () => {
|
|||
place-self: center;
|
||||
}
|
||||
|
||||
.place-self-center-safe {
|
||||
place-self: safe center;
|
||||
}
|
||||
|
||||
.place-self-end {
|
||||
place-self: end;
|
||||
}
|
||||
|
||||
.place-self-end-safe {
|
||||
place-self: safe end;
|
||||
}
|
||||
|
||||
.place-self-start {
|
||||
place-self: start;
|
||||
}
|
||||
|
|
@ -8345,7 +8415,9 @@ test('self', async () => {
|
|||
'self-auto',
|
||||
'self-start',
|
||||
'self-end',
|
||||
'self-end-safe',
|
||||
'self-center',
|
||||
'self-center-safe',
|
||||
'self-stretch',
|
||||
'self-baseline',
|
||||
]),
|
||||
|
|
@ -8362,10 +8434,18 @@ test('self', async () => {
|
|||
align-self: center;
|
||||
}
|
||||
|
||||
.self-center-safe {
|
||||
align-self: safe center;
|
||||
}
|
||||
|
||||
.self-end {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.self-end-safe {
|
||||
align-self: safe flex-end;
|
||||
}
|
||||
|
||||
.self-start {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
|
@ -8399,7 +8479,9 @@ test('justify-self', async () => {
|
|||
'justify-self-auto',
|
||||
'justify-self-start',
|
||||
'justify-self-end',
|
||||
'justify-self-end-safe',
|
||||
'justify-self-center',
|
||||
'justify-self-center-safe',
|
||||
'justify-self-stretch',
|
||||
'justify-self-baseline',
|
||||
]),
|
||||
|
|
@ -8412,10 +8494,18 @@ test('justify-self', async () => {
|
|||
justify-self: center;
|
||||
}
|
||||
|
||||
.justify-self-center-safe {
|
||||
justify-self: safe center;
|
||||
}
|
||||
|
||||
.justify-self-end {
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.justify-self-end-safe {
|
||||
justify-self: safe flex-end;
|
||||
}
|
||||
|
||||
.justify-self-start {
|
||||
justify-self: flex-start;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from './ast'
|
||||
import type { Candidate, CandidateModifier, NamedUtilityValue } from './candidate'
|
||||
import type { DesignSystem } from './design-system'
|
||||
import { enableBaselineLast, enableWrapAnywhere } from './feature-flags'
|
||||
import { enableBaselineLast, enableSafeAlignment, enableWrapAnywhere } from './feature-flags'
|
||||
import type { Theme, ThemeKey } from './theme'
|
||||
import { compareBreakpoints } from './utils/compare-breakpoints'
|
||||
import { DefaultMap } from './utils/default-map'
|
||||
|
|
@ -1856,6 +1856,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('place-content-center', [['place-content', 'center']])
|
||||
staticUtility('place-content-start', [['place-content', 'start']])
|
||||
staticUtility('place-content-end', [['place-content', 'end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('place-content-center-safe', [['place-content', 'safe center']])
|
||||
staticUtility('place-content-end-safe', [['place-content', 'safe end']])
|
||||
}
|
||||
staticUtility('place-content-between', [['place-content', 'space-between']])
|
||||
staticUtility('place-content-around', [['place-content', 'space-around']])
|
||||
staticUtility('place-content-evenly', [['place-content', 'space-evenly']])
|
||||
|
|
@ -1865,6 +1869,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('place-items-center', [['place-items', 'center']])
|
||||
staticUtility('place-items-start', [['place-items', 'start']])
|
||||
staticUtility('place-items-end', [['place-items', 'end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('place-items-center-safe', [['place-items', 'safe center']])
|
||||
staticUtility('place-items-end-safe', [['place-items', 'safe end']])
|
||||
}
|
||||
staticUtility('place-items-baseline', [['place-items', 'baseline']])
|
||||
staticUtility('place-items-stretch', [['place-items', 'stretch']])
|
||||
|
||||
|
|
@ -1872,6 +1880,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('content-center', [['align-content', 'center']])
|
||||
staticUtility('content-start', [['align-content', 'flex-start']])
|
||||
staticUtility('content-end', [['align-content', 'flex-end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('content-center-safe', [['align-content', 'safe center']])
|
||||
staticUtility('content-end-safe', [['align-content', 'safe flex-end']])
|
||||
}
|
||||
staticUtility('content-between', [['align-content', 'space-between']])
|
||||
staticUtility('content-around', [['align-content', 'space-around']])
|
||||
staticUtility('content-evenly', [['align-content', 'space-evenly']])
|
||||
|
|
@ -1881,6 +1893,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('items-center', [['align-items', 'center']])
|
||||
staticUtility('items-start', [['align-items', 'flex-start']])
|
||||
staticUtility('items-end', [['align-items', 'flex-end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('items-center-safe', [['align-items', 'safe center']])
|
||||
staticUtility('items-end-safe', [['align-items', 'safe flex-end']])
|
||||
}
|
||||
staticUtility('items-baseline', [['align-items', 'baseline']])
|
||||
if (enableBaselineLast) {
|
||||
staticUtility('items-baseline-last', [['align-items', 'last baseline']])
|
||||
|
|
@ -1891,6 +1907,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('justify-center', [['justify-content', 'center']])
|
||||
staticUtility('justify-start', [['justify-content', 'flex-start']])
|
||||
staticUtility('justify-end', [['justify-content', 'flex-end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('justify-center-safe', [['justify-content', 'safe center']])
|
||||
staticUtility('justify-end-safe', [['justify-content', 'safe flex-end']])
|
||||
}
|
||||
staticUtility('justify-between', [['justify-content', 'space-between']])
|
||||
staticUtility('justify-around', [['justify-content', 'space-around']])
|
||||
staticUtility('justify-evenly', [['justify-content', 'space-evenly']])
|
||||
|
|
@ -1901,6 +1921,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('justify-items-center', [['justify-items', 'center']])
|
||||
staticUtility('justify-items-start', [['justify-items', 'start']])
|
||||
staticUtility('justify-items-end', [['justify-items', 'end']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('justify-items-center-safe', [['justify-items', 'safe center']])
|
||||
staticUtility('justify-items-end-safe', [['justify-items', 'safe end']])
|
||||
}
|
||||
staticUtility('justify-items-stretch', [['justify-items', 'stretch']])
|
||||
|
||||
spacingUtility('gap', ['--gap', '--spacing'], (value) => [decl('gap', value)])
|
||||
|
|
@ -1981,12 +2005,20 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('place-self-start', [['place-self', 'start']])
|
||||
staticUtility('place-self-end', [['place-self', 'end']])
|
||||
staticUtility('place-self-center', [['place-self', 'center']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('place-self-end-safe', [['place-self', 'safe end']])
|
||||
staticUtility('place-self-center-safe', [['place-self', 'safe center']])
|
||||
}
|
||||
staticUtility('place-self-stretch', [['place-self', 'stretch']])
|
||||
|
||||
staticUtility('self-auto', [['align-self', 'auto']])
|
||||
staticUtility('self-start', [['align-self', 'flex-start']])
|
||||
staticUtility('self-end', [['align-self', 'flex-end']])
|
||||
staticUtility('self-center', [['align-self', 'center']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('self-end-safe', [['align-self', 'safe flex-end']])
|
||||
staticUtility('self-center-safe', [['align-self', 'safe center']])
|
||||
}
|
||||
staticUtility('self-stretch', [['align-self', 'stretch']])
|
||||
staticUtility('self-baseline', [['align-self', 'baseline']])
|
||||
|
||||
|
|
@ -1994,6 +2026,10 @@ export function createUtilities(theme: Theme) {
|
|||
staticUtility('justify-self-start', [['justify-self', 'flex-start']])
|
||||
staticUtility('justify-self-end', [['justify-self', 'flex-end']])
|
||||
staticUtility('justify-self-center', [['justify-self', 'center']])
|
||||
if (enableSafeAlignment) {
|
||||
staticUtility('justify-self-end-safe', [['justify-self', 'safe flex-end']])
|
||||
staticUtility('justify-self-center-safe', [['justify-self', 'safe center']])
|
||||
}
|
||||
staticUtility('justify-self-stretch', [['justify-self', 'stretch']])
|
||||
|
||||
for (let value of ['auto', 'hidden', 'clip', 'visible', 'scroll']) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue