From 8436d02df75b27cc111200239aa45ce1d0b6fabd Mon Sep 17 00:00:00 2001 From: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:07:50 -0500 Subject: [PATCH 1/3] Only set border-style for appropriate border side Fixes #13121. Something to consider is that this implementation will still have issues if we ever implement support for utilities like `border-r-dashed`. 6am and I just woke up and am going to the gym now but leaving this as a note to consider when I get back before merging :) --- .../src/__snapshots__/utilities.test.ts.snap | 180 ++++++++++-------- packages/tailwindcss/src/utilities.test.ts | 25 ++- packages/tailwindcss/src/utilities.ts | 62 ++++-- packages/tailwindcss/tests/ui.spec.ts | 29 +++ playgrounds/vite/src/app.tsx | 8 +- 5 files changed, 195 insertions(+), 109 deletions(-) diff --git a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap index fcd970cf0219..6e9d6e44a57a 100644 --- a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap @@ -118,52 +118,52 @@ exports[`border-b-* 1`] = ` } .border-b { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 1px; } .border-b-0 { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 0; } .border-b-123 { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 123px; } .border-b-2 { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 2px; } .border-b-4 { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 4px; } .border-b-\\[12px\\] { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: 12px; } .border-b-\\[length\\:--my-width\\], .border-b-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: var(--my-width); } .border-b-\\[medium\\] { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: medium; } .border-b-\\[thick\\] { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: thick; } .border-b-\\[thin\\] { - border-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: thin; } @@ -227,52 +227,52 @@ exports[`border-e-* 1`] = ` } .border-e { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 1px; } .border-e-0 { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 0; } .border-e-123 { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 123px; } .border-e-2 { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 2px; } .border-e-4 { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 4px; } .border-e-\\[12px\\] { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: 12px; } .border-e-\\[length\\:--my-width\\], .border-e-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: var(--my-width); } .border-e-\\[medium\\] { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: medium; } .border-e-\\[thick\\] { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: thick; } .border-e-\\[thin\\] { - border-style: var(--tw-border-style); + border-inline-end-style: var(--tw-border-style); border-inline-end-width: thin; } @@ -336,52 +336,52 @@ exports[`border-l-* 1`] = ` } .border-l { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 1px; } .border-l-0 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 0; } .border-l-123 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 123px; } .border-l-2 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 2px; } .border-l-4 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 4px; } .border-l-\\[12px\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: 12px; } .border-l-\\[length\\:--my-width\\], .border-l-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: var(--my-width); } .border-l-\\[medium\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: medium; } .border-l-\\[thick\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: thick; } .border-l-\\[thin\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); border-left-width: thin; } @@ -445,52 +445,52 @@ exports[`border-r-* 1`] = ` } .border-r { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 1px; } .border-r-0 { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 0; } .border-r-123 { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 123px; } .border-r-2 { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 2px; } .border-r-4 { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 4px; } .border-r-\\[12px\\] { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: 12px; } .border-r-\\[length\\:--my-width\\], .border-r-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: var(--my-width); } .border-r-\\[medium\\] { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: medium; } .border-r-\\[thick\\] { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: thick; } .border-r-\\[thin\\] { - border-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-right-width: thin; } @@ -554,52 +554,52 @@ exports[`border-s-* 1`] = ` } .border-s { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 1px; } .border-s-0 { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 0; } .border-s-123 { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 123px; } .border-s-2 { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 2px; } .border-s-4 { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 4px; } .border-s-\\[12px\\] { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: 12px; } .border-s-\\[length\\:--my-width\\], .border-s-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: var(--my-width); } .border-s-\\[medium\\] { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: medium; } .border-s-\\[thick\\] { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: thick; } .border-s-\\[thin\\] { - border-style: var(--tw-border-style); + border-inline-start-style: var(--tw-border-style); border-inline-start-width: thin; } @@ -663,52 +663,52 @@ exports[`border-t-* 1`] = ` } .border-t { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 1px; } .border-t-0 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 0; } .border-t-123 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 123px; } .border-t-2 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 2px; } .border-t-4 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 4px; } .border-t-\\[12px\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: 12px; } .border-t-\\[length\\:--my-width\\], .border-t-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: var(--my-width); } .border-t-\\[medium\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: medium; } .border-t-\\[thick\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: thick; } .border-t-\\[thin\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); border-top-width: thin; } @@ -772,61 +772,71 @@ exports[`border-x-* 1`] = ` } .border-x { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 1px; border-right-width: 1px; } .border-x-0 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 0; border-right-width: 0; } .border-x-123 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 123px; border-right-width: 123px; } .border-x-2 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 2px; border-right-width: 2px; } .border-x-4 { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 4px; border-right-width: 4px; } .border-x-\\[12px\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: 12px; border-right-width: 12px; } .border-x-\\[length\\:--my-width\\], .border-x-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: var(--my-width); border-right-width: var(--my-width); } .border-x-\\[medium\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: medium; border-right-width: medium; } .border-x-\\[thick\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: thick; border-right-width: thick; } .border-x-\\[thin\\] { - border-style: var(--tw-border-style); + border-left-style: var(--tw-border-style); + border-right-style: var(--tw-border-style); border-left-width: thin; border-right-width: thin; } @@ -902,61 +912,71 @@ exports[`border-y-* 1`] = ` } .border-y { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 1px; border-bottom-width: 1px; } .border-y-0 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 0; border-bottom-width: 0; } .border-y-123 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 123px; border-bottom-width: 123px; } .border-y-2 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 2px; border-bottom-width: 2px; } .border-y-4 { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 4px; border-bottom-width: 4px; } .border-y-\\[12px\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: 12px; border-bottom-width: 12px; } .border-y-\\[length\\:--my-width\\], .border-y-\\[line-width\\:--my-width\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: var(--my-width); border-bottom-width: var(--my-width); } .border-y-\\[medium\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: medium; border-bottom-width: medium; } .border-y-\\[thick\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: thick; border-bottom-width: thick; } .border-y-\\[thin\\] { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-top-width: thin; border-bottom-width: thin; } diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 47db575006d4..8fd0dcf6782b 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -4831,25 +4831,25 @@ test('divide-x', () => { ), ).toMatchInlineSnapshot(` ":where(.divide-x > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-inline-style: var(--tw-border-style); border-inline-end-width: calc(1px * var(--tw-divide-x-reverse)); border-inline-start-width: calc(1px * calc(1 - var(--tw-divide-x-reverse))); } :where(.divide-x-123 > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-inline-style: var(--tw-border-style); border-inline-end-width: calc(123px * var(--tw-divide-x-reverse)); border-inline-start-width: calc(123px * calc(1 - var(--tw-divide-x-reverse))); } :where(.divide-x-4 > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-inline-style: var(--tw-border-style); border-inline-end-width: calc(4px * var(--tw-divide-x-reverse)); border-inline-start-width: calc(4px * calc(1 - var(--tw-divide-x-reverse))); } :where(.divide-x-\\[4px\\] > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-inline-style: var(--tw-border-style); border-inline-end-width: calc(4px * var(--tw-divide-x-reverse)); border-inline-start-width: calc(4px * calc(1 - var(--tw-divide-x-reverse))); } @@ -4886,7 +4886,7 @@ test('divide-x with custom default border width', () => { } :where(.divide-x > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-inline-style: var(--tw-border-style); border-inline-end-width: calc(2px * var(--tw-divide-x-reverse)); border-inline-start-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); } @@ -4915,25 +4915,29 @@ test('divide-y', () => { ), ).toMatchInlineSnapshot(` ":where(.divide-y > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); } :where(.divide-y-123 > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: calc(123px * var(--tw-divide-y-reverse)); border-top-width: calc(123px * calc(1 - var(--tw-divide-y-reverse))); } :where(.divide-y-4 > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); } :where(.divide-y-\\[4px\\] > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); } @@ -4970,7 +4974,8 @@ test('divide-y with custom default border width', () => { } :where(.divide-y > :not([hidden]) ~ :not([hidden])) { - border-style: var(--tw-border-style); + border-top-style: var(--tw-border-style); + border-bottom-style: var(--tw-border-style); border-bottom-width: calc(2px * var(--tw-divide-y-reverse)); border-top-width: calc(2px * calc(1 - var(--tw-divide-y-reverse))); } diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 071558b52106..9e50da48f336 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -2089,7 +2089,7 @@ export function createUtilities(theme: Theme) { let value = theme.get(['--default-border-width']) ?? '1px' let decls = desc.width(value) if (!decls) return - return [borderProperties(), decl('border-style', 'var(--tw-border-style)'), ...decls] + return [borderProperties(), ...decls] } if (candidate.value.kind === 'arbitrary') { @@ -2102,7 +2102,7 @@ export function createUtilities(theme: Theme) { case 'length': { let decls = desc.width(value) if (!decls) return - return [borderProperties(), decl('border-style', 'var(--tw-border-style)'), ...decls] + return [borderProperties(), ...decls] } default: { value = asColor(value, candidate.modifier, theme) @@ -2127,13 +2127,13 @@ export function createUtilities(theme: Theme) { if (value) { let decls = desc.width(value) if (!decls) return - return [borderProperties(), decl('border-style', 'var(--tw-border-style)'), ...decls] + return [borderProperties(), ...decls] } if (!Number.isNaN(Number(candidate.value.value))) { let decls = desc.width(`${candidate.value.value}px`) if (!decls) return - return [borderProperties(), decl('border-style', 'var(--tw-border-style)'), ...decls] + return [borderProperties(), ...decls] } } }) @@ -2154,47 +2154,78 @@ export function createUtilities(theme: Theme) { } borderSideUtility('border', { - width: (value) => [decl('border-width', value)], + width: (value) => [ + decl('border-style', 'var(--tw-border-style)'), + decl('border-width', value), + ], color: (value) => [decl('border-color', value)], }) borderSideUtility('border-x', { - width: (value) => [decl('border-left-width', value), decl('border-right-width', value)], + width: (value) => [ + decl('border-left-style', 'var(--tw-border-style)'), + decl('border-right-style', 'var(--tw-border-style)'), + decl('border-left-width', value), + decl('border-right-width', value), + ], color: (value) => [decl('border-left-color', value), decl('border-right-color', value)], }) borderSideUtility('border-y', { - width: (value) => [decl('border-top-width', value), decl('border-bottom-width', value)], + width: (value) => [ + decl('border-top-style', 'var(--tw-border-style)'), + decl('border-bottom-style', 'var(--tw-border-style)'), + decl('border-top-width', value), + decl('border-bottom-width', value), + ], color: (value) => [decl('border-top-color', value), decl('border-bottom-color', value)], }) borderSideUtility('border-s', { - width: (value) => [decl('border-inline-start-width', value)], + width: (value) => [ + decl('border-inline-start-style', 'var(--tw-border-style)'), + decl('border-inline-start-width', value), + ], color: (value) => [decl('border-inline-start-color', value)], }) borderSideUtility('border-e', { - width: (value) => [decl('border-inline-end-width', value)], + width: (value) => [ + decl('border-inline-end-style', 'var(--tw-border-style)'), + decl('border-inline-end-width', value), + ], color: (value) => [decl('border-inline-end-color', value)], }) borderSideUtility('border-t', { - width: (value) => [decl('border-top-width', value)], + width: (value) => [ + decl('border-top-style', 'var(--tw-border-style)'), + decl('border-top-width', value), + ], color: (value) => [decl('border-top-color', value)], }) borderSideUtility('border-r', { - width: (value) => [decl('border-right-width', value)], + width: (value) => [ + decl('border-right-style', 'var(--tw-border-style)'), + decl('border-right-width', value), + ], color: (value) => [decl('border-right-color', value)], }) borderSideUtility('border-b', { - width: (value) => [decl('border-bottom-width', value)], + width: (value) => [ + decl('border-bottom-style', 'var(--tw-border-style)'), + decl('border-bottom-width', value), + ], color: (value) => [decl('border-bottom-color', value)], }) borderSideUtility('border-l', { - width: (value) => [decl('border-left-width', value)], + width: (value) => [ + decl('border-left-style', 'var(--tw-border-style)'), + decl('border-left-width', value), + ], color: (value) => [decl('border-left-color', value)], }) @@ -2208,7 +2239,7 @@ export function createUtilities(theme: Theme) { rule(':where(& > :not([hidden]) ~ :not([hidden]))', [ decl('--tw-sort', 'divide-x-width'), borderProperties(), - decl('border-style', 'var(--tw-border-style)'), + decl('border-inline-style', 'var(--tw-border-style)'), decl('border-inline-end-width', `calc(${value} * var(--tw-divide-x-reverse))`), decl( 'border-inline-start-width', @@ -2228,7 +2259,8 @@ export function createUtilities(theme: Theme) { rule(':where(& > :not([hidden]) ~ :not([hidden]))', [ decl('--tw-sort', 'divide-y-width'), borderProperties(), - decl('border-style', 'var(--tw-border-style)'), + decl('border-top-style', 'var(--tw-border-style)'), + decl('border-bottom-style', 'var(--tw-border-style)'), decl('border-bottom-width', `calc(${value} * var(--tw-divide-y-reverse))`), decl('border-top-width', `calc(${value} * calc(1 - var(--tw-divide-y-reverse)))`), ]), diff --git a/packages/tailwindcss/tests/ui.spec.ts b/packages/tailwindcss/tests/ui.spec.ts index 45831436c1f9..7e975ac2f385 100644 --- a/packages/tailwindcss/tests/ui.spec.ts +++ b/packages/tailwindcss/tests/ui.spec.ts @@ -192,6 +192,35 @@ test('borders can be added without a border-style utility', async ({ page }) => expect(await getPropertyValue('#x', 'border')).toEqual('2px solid rgb(0, 0, 0)') }) +test('borders can be added to a single side a border-style utility', async ({ page }) => { + let { getPropertyValue } = await render( + page, + html`