From f11ece4b94d9fd23738d1c572bd28f5197a90e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Kuna?= <1282324+codecalm@users.noreply.github.com> Date: Fri, 14 Aug 2026 01:15:54 +0200 Subject: [PATCH] Add `bg-pattern-opacity-*` utilities; patterns no longer draw borders (#2873) --- .changeset/pattern-opacity-css.md | 7 + core/scss/_utilities.scss | 7 - core/scss/_variables.scss | 12 ++ core/scss/ui/_patterns.scss | 137 +++++------------- .../ui/utilities/background-patterns.mdx | 50 ++++++- preview/pages/patterns.astro | 65 ++++++++- .../pages/background-pattern-colors.astro | 2 +- .../pages/background-pattern-utilities.astro | 2 +- shared/ui/BackgroundPattern.astro | 2 +- 9 files changed, 167 insertions(+), 117 deletions(-) create mode 100644 .changeset/pattern-opacity-css.md diff --git a/.changeset/pattern-opacity-css.md b/.changeset/pattern-opacity-css.md new file mode 100644 index 000000000..016034ffb --- /dev/null +++ b/.changeset/pattern-opacity-css.md @@ -0,0 +1,7 @@ +--- +"@tabler/core": minor +"@tabler/docs": patch +"@tabler/preview": patch +--- + +Added `--pattern-opacity-factor` and `.bg-pattern-opacity-*` utilities for background patterns. diff --git a/core/scss/_utilities.scss b/core/scss/_utilities.scss index f1e16722e..d73e25014 100644 --- a/core/scss/_utilities.scss +++ b/core/scss/_utilities.scss @@ -564,13 +564,6 @@ $utilities: map.merge( class: column-gap, values: $spacers, ), - 'bg-pattern': ( - property: background, - class: bg-pattern, - values: ( - transparent: #{url-svg('')} repeat center/16px 16px, - ), - ), 'bg-gradient': ( property: background, class: bg-gradient, diff --git a/core/scss/_variables.scss b/core/scss/_variables.scss index cc37c5c01..bc4691d78 100644 --- a/core/scss/_variables.scss +++ b/core/scss/_variables.scss @@ -2191,6 +2191,18 @@ $pattern-size-sm: 0.25rem !default; $pattern-size-md: 0.5rem !default; $pattern-size-lg: 0.75rem !default; $pattern-size-xl: 1rem !default; +$pattern-opacity: 10% !default; +$pattern-opacity-factor: 1 !default; +$pattern-opacity-lighter: 6% !default; +$pattern-opacity-light: 8% !default; +$pattern-opacity-dark: 20% !default; +$pattern-opacity-darker: 50% !default; +$pattern-opacities: ( + lighter: $pattern-opacity-lighter, + light: $pattern-opacity-light, + dark: $pattern-opacity-dark, + darker: $pattern-opacity-darker, +) !default; // Markdown $markdown-heading-margin-top: 2.5rem !default; diff --git a/core/scss/ui/_patterns.scss b/core/scss/ui/_patterns.scss index 68a43918c..a8c391ea3 100644 --- a/core/scss/ui/_patterns.scss +++ b/core/scss/ui/_patterns.scss @@ -1,180 +1,128 @@ @use '../config' as *; -.bg-pattern-diagonal { +@mixin pattern-base($opacity: $pattern-opacity) { --pattern-color: var(--body-color); --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - background-image: repeating-linear-gradient(-45deg, var(--pattern-fill) 0 1px, transparent 0 50%); + --pattern-opacity: calc(var(--pattern-opacity-factor, #{$pattern-opacity-factor}) * #{$opacity}); + --pattern-fill: color-mix(in oklch, var(--pattern-color) var(--pattern-opacity), transparent); background-clip: padding-box; +} + +.bg-pattern-transparent { + @include pattern-base(); + background-image: repeating-conic-gradient(var(--pattern-fill) 0% 25%, transparent 0% 50%); + background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); +} + +.bg-pattern-diagonal { + @include pattern-base(); + background-image: repeating-linear-gradient(-45deg, var(--pattern-fill) 0 1px, transparent 0 50%); background-size: var(--pattern-size) var(--pattern-size); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-diagonal-2 { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(); background-image: repeating-linear-gradient(45deg, var(--pattern-fill) 0 1px, transparent 0 50%); - background-clip: padding-box; background-size: var(--pattern-size) var(--pattern-size); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-dots { - --pattern-color: var(--body-color); - --pattern-size: 5px; - --pattern-dot: 0.5px; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 20%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - background-image: radial-gradient(circle, var(--pattern-fill) var(--pattern-dot), transparent var(--pattern-dot)), radial-gradient(circle, var(--pattern-fill) var(--pattern-dot), transparent var(--pattern-dot)); + @include pattern-base(20%); + --pattern-dot: max(1px, calc(var(--pattern-size) * 0.1)); + background-image: radial-gradient(circle, var(--pattern-fill) var(--pattern-dot), transparent calc(var(--pattern-dot) + 0.5px)), radial-gradient(circle, var(--pattern-fill) var(--pattern-dot), transparent calc(var(--pattern-dot) + 0.5px)); background-position: 0 0, - calc(var(--pattern-size) / 2) calc(var(--pattern-size) / 2); - background-clip: padding-box; - background-size: var(--pattern-size) var(--pattern-size); - border: var(--border-width) var(--border-style) var(--pattern-border); + calc(var(--pattern-size)) calc(var(--pattern-size)); + background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); } .bg-pattern-rectangles { - --pattern-color: var(--body-color); - --pattern-fill: color-mix(in oklch, var(--pattern-color) 3%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-size: #{$pattern-size}; + @include pattern-base(3%); background-image: repeating-linear-gradient(45deg, var(--pattern-fill) 25%, transparent 25%, transparent 75%, var(--pattern-fill) 75%, var(--pattern-fill)), repeating-linear-gradient(45deg, var(--pattern-fill) 25%, transparent 25%, transparent 75%, var(--pattern-fill) 75%, var(--pattern-fill)); background-position: -1px -1px, calc(var(--pattern-size) - 1px) calc(var(--pattern-size) - 1px); - background-clip: padding-box; background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-lines { - --pattern-color: var(--body-color); - --pattern-fill: color-mix(in oklch, var(--pattern-color) 6%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-size: #{$pattern-size}; + @include pattern-base(6%); background-image: repeating-linear-gradient(0deg, var(--pattern-fill), var(--pattern-fill) 1px, transparent 1px, transparent); background-position: -1px -1px; - background-clip: padding-box; background-size: var(--pattern-size) var(--pattern-size); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-lines-vertical { - --pattern-color: var(--body-color); - --pattern-fill: color-mix(in oklch, var(--pattern-color) 6%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-size: #{$pattern-size}; + @include pattern-base(6%); background-image: repeating-linear-gradient(90deg, var(--pattern-fill), var(--pattern-fill) 1px, transparent 1px, transparent); background-position: -1px -1px; - background-clip: padding-box; background-size: var(--pattern-size) var(--pattern-size); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-grid { - --pattern-color: var(--body-color); - --pattern-fill: color-mix(in oklch, var(--pattern-color) 6%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-size: #{$pattern-size}; + @include pattern-base(6%); background-image: linear-gradient(to right, var(--pattern-fill) 1px, transparent 1px), linear-gradient(to bottom, var(--pattern-fill) 1px, transparent 1px); background-position: -1px -1px, -1px -1px; - background-clip: padding-box; background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-grid-diagonal { - --pattern-color: var(--body-color); - --pattern-fill: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-size: #{$pattern-size}; + @include pattern-base(); background-image: linear-gradient(45deg, transparent 49%, var(--pattern-fill) 49%, var(--pattern-fill) 51%, transparent 51%), linear-gradient(-45deg, transparent 49%, var(--pattern-fill) 49%, var(--pattern-fill) 51%, transparent 51%); background-position: center center; - background-clip: padding-box; background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-blueprint { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-line: color-mix(in oklch, var(--pattern-color) 6%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(6%); + --pattern-line: var(--pattern-fill); background-image: linear-gradient(var(--pattern-line) 2px, transparent 2px), linear-gradient(90deg, var(--pattern-line) 2px, transparent 2px), linear-gradient(var(--pattern-line) 1px, transparent 1px), linear-gradient(90deg, var(--pattern-line) 1px, transparent 1px); background-position: -3px -3px, -3px -3px, -2px -2px, -2px -2px; - background-clip: padding-box; background-size: calc(var(--pattern-size) * 10) calc(var(--pattern-size) * 10), calc(var(--pattern-size) * 10) calc(var(--pattern-size) * 10), calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2), calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-cross-dots { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(); background-image: radial-gradient(var(--pattern-fill) 1px, transparent 1px), radial-gradient(var(--pattern-fill) 1px, transparent 1px); background-position: 0 0, var(--pattern-size) var(--pattern-size); - background-clip: padding-box; background-size: calc(var(--pattern-size) * 2) calc(var(--pattern-size) * 2); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-circles { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 10%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(); background-image: radial-gradient(circle at center top, transparent 9%, var(--pattern-fill) 10%, var(--pattern-fill) 15%, transparent 16%), radial-gradient(circle at center bottom, transparent 9%, var(--pattern-fill) 10%, var(--pattern-fill) 15%, transparent 16%), radial-gradient(circle at right center, transparent 9%, var(--pattern-fill) 10%, var(--pattern-fill) 15%, transparent 16%), radial-gradient(circle at left center, transparent 9%, var(--pattern-fill) 10%, var(--pattern-fill) 15%, transparent 16%); background-position: 0 0; background-size: calc(var(--pattern-size) * 3) calc(var(--pattern-size) * 3); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-diagonal-stripes { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 5%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(5%); background-image: repeating-linear-gradient(45deg, transparent, transparent var(--pattern-size), var(--pattern-fill) var(--pattern-size), var(--pattern-fill) calc(2 * var(--pattern-size))); background-repeat: no-repeat; - background-clip: padding-box; - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-diagonal-stripes-2 { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 5%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(5%); background-image: repeating-linear-gradient(-45deg, transparent, transparent var(--pattern-size), var(--pattern-fill) var(--pattern-size), var(--pattern-fill) calc(2 * var(--pattern-size))); background-repeat: no-repeat; - background-clip: padding-box; - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-zigzag { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 5%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(5%); background: linear-gradient(135deg, var(--pattern-fill) 25%, transparent 25%) calc(-1 * var(--pattern-size)) 0, linear-gradient(225deg, var(--pattern-fill) 25%, transparent 25%) calc(-1 * var(--pattern-size)) 0, @@ -182,28 +130,17 @@ linear-gradient(45deg, var(--pattern-fill) 25%, transparent 25%); background-clip: padding-box; background-size: calc(2 * var(--pattern-size)) calc(2 * var(--pattern-size)); - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-vertical-stripes { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 5%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(5%); background-image: repeating-linear-gradient(90deg, transparent, transparent var(--pattern-size), var(--pattern-fill) var(--pattern-size), var(--pattern-fill) calc(2 * var(--pattern-size))); - background-clip: padding-box; - border: var(--border-width) var(--border-style) var(--pattern-border); } .bg-pattern-horizontal-stripes { - --pattern-color: var(--body-color); - --pattern-size: #{$pattern-size}; - --pattern-fill: color-mix(in oklch, var(--pattern-color) 5%, transparent); - --pattern-border: color-mix(in oklch, var(--pattern-color) 10%, transparent); + @include pattern-base(5%); background-image: repeating-linear-gradient(0deg, transparent, transparent var(--pattern-size), var(--pattern-fill) var(--pattern-size), var(--pattern-fill) calc(2 * var(--pattern-size))); background-position: -1px -1px; - background-clip: padding-box; - border: var(--border-width) var(--border-style) var(--pattern-border); } // Color variants @@ -226,3 +163,9 @@ $sizes: ( --pattern-size: #{$value}; } } + +@each $key, $value in $pattern-opacities { + .bg-pattern-opacity-#{$key} { + --pattern-opacity: #{$value}; + } +} diff --git a/docs/content/ui/utilities/background-patterns.mdx b/docs/content/ui/utilities/background-patterns.mdx index 74502de47..7268979a7 100644 --- a/docs/content/ui/utilities/background-patterns.mdx +++ b/docs/content/ui/utilities/background-patterns.mdx @@ -42,7 +42,7 @@ Here are the available pattern types: {patterns.map((pattern, i) => { return (
.bg-pattern-{ pattern }
.bg-pattern-{ color[0] } .bg-pattern-{ color[0] } .bg-pattern-sm
.bg-pattern-md
.bg-pattern-lg
.bg-pattern-xl
.bg-pattern-opacity-lighter
+ .bg-pattern-opacity-light
+ .bg-pattern-opacity-dark
+ .bg-pattern-opacity-darker
+ .bg-pattern-{pattern}
.bg-pattern-{color}
.bg-pattern-{size}
lighter, light, dark, or darker..bg-pattern-opacity-{opacity}
+ .bg-pattern-transparent
+ .bg-pattern-grid.bg-pattern-primary.bg-pattern-lg.bg-pattern-opacity-light
+ .bg-pattern-diagonal-stripes-2.bg-pattern-azure.bg-pattern-opacity-dark
+ .bg-pattern-dots.bg-pattern-red.bg-pattern-sm.bg-pattern-opacity-darker
+ .bg-pattern-diagonal.
+ .bg-pattern-opacity-light.
+ .bg-pattern-{color}
.bg-pattern-{pattern}