Skip to content

Commit

Permalink
feat: always use css layers
Browse files Browse the repository at this point in the history
closes #3400
closes #20232
  • Loading branch information
KaelWD committed Oct 31, 2024
1 parent 8c5a2b9 commit f7123c6
Show file tree
Hide file tree
Showing 38 changed files with 564 additions and 556 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@
"overrides": {
"@testing-library/dom": "npm:@vuetify/[email protected]",
"@types/node": "22.5.4",
"tough-cookie": "5.0.0-rc.4"
"tough-cookie": "5.0.0-rc.4",
"rrweb-cssom": "0.8.0"
}
}
}
1 change: 1 addition & 0 deletions packages/docs/src/data/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"activeIcon": "mdi-palette",
"items": [
"css-reset",
"layers",
"transitions",
"colors",
{ "divider": true },
Expand Down
24 changes: 0 additions & 24 deletions packages/docs/src/pages/en/features/sass-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,30 +247,6 @@ Color packs are handy for quickly applying a color to a component but mostly unu
);
```

## Enabling CSS cascade layers

::: success
This feature was introduced in [v3.6.0 (Nebula)](/getting-started/release-notes/?version=v3.6.0)
:::

[Cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) are a modern CSS feature that makes it easier to write custom styles without having to deal with specificity issues and `!important`. This will be included by default in Vuetify 4 but can optionally be used now:

```scss { resource="src/styles/settings.scss" }
@forward 'vuetify/settings' with (
$layers: true,
);
```

Import order of stylesheets becomes much more important with layers enabled, `import 'vuetify/styles'` or a file containing `@use 'vuetify'` **must** be loaded *before* any components or the CSS reset will take precedence over component styles and break everything. If you have separate plugin files make sure to import vuetify's before `App.vue`.

Your own styles will always<sup>*</sup> override vuetify's if you don't use `@layer` yourself, or you can specify an order for custom layers in a stylesheet loaded before vuetify.

```css { resource="src/styles/layers.css" }
@layer base, vuetify, overrides;
```

\* Layers invert `!important`, so anything trying to override an important vuetify style must also be in a layer. { class="text-caption" }

## Caveats

When using sass variables, there are a few considerations to be aware of.
Expand Down
28 changes: 28 additions & 0 deletions packages/docs/src/pages/en/styles/layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
meta:
title: CSS Layers
description: Vuetify 4 uses cascade layers to avoid specificity problems
keywords: cascade layers, vuetify !important
related:
- /features/sass-variables/
---

::: success
This feature was introduced in [v3.6.0 (Nebula)](/getting-started/release-notes/?version=v3.6.0)
:::

# CSS Layers

[Cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) are a modern CSS feature that makes it easier to write custom styles without having to deal with specificity issues and `!important`.

Import order of stylesheets becomes much more important with layers, therefore `import 'vuetify/styles'` or a file containing `@use 'vuetify'` **must** be loaded *before* any components or the CSS reset will take precedence over component styles and break everything. If you have separate plugin files make sure to import the vuetify plugin before `App.vue` or any other components.

Your own styles will always<sup>*</sup> override vuetify's if you don't use `@layer` yourself, or you can specify an order for custom layers in a stylesheet loaded before vuetify.

```css { resource="src/styles/layers.css" }
@layer base, vuetify, overrides;
```

Vuetify also defines an empty `vuetify.custom` layer that you can put your overrides in, this does not need declaring in advance and can be used immediately.

\* Layers invert `!important`, so anything trying to override an !important vuetify style must also be in a layer. We try to avoid !important for this reason but a few still exist { class="text-caption" }
8 changes: 4 additions & 4 deletions packages/vuetify/src/components/VBtn/VBtn.sass
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,8 @@
opacity: $button-disabled-opacity
@else
opacity: 1
&.v-btn
// specificity has to be higher to override theme !important
color: rgba(var(--v-theme-on-surface), $button-disabled-opacity) !important
@include tools.layer('trumps')
color: rgba(var(--v-theme-on-surface), $button-disabled-opacity)

&.v-btn--variant-elevated,
&.v-btn--variant-flat
Expand All @@ -101,7 +100,8 @@
color: rgba(var(--v-theme-on-surface), $button-disabled-opacity)
background: rgb(var(--v-theme-surface))
@else
background: rgb(var(--v-theme-surface)) !important
@include tools.layer('trumps')
background: rgb(var(--v-theme-surface))

.v-btn__overlay
// __overlay uses currentColor, so we need to divide
Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VCarousel/VCarousel.sass
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@
.v-carousel--vertical-delimiters
.v-carousel__controls
flex-direction: column
height: 100% !important
height: 100%
width: $carousel-controls-size
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
@include tools.layer('components')
.v-color-picker-preview__alpha
.v-slider-track__background
background-color: transparent !important
@include tools.layer('overrides')
background-color: transparent

@include tools.ltr()
background-image: linear-gradient(to right, transparent, var(--v-color-picker-color-hsv))
Expand Down Expand Up @@ -54,7 +55,8 @@
position: relative
width: 100%

margin: 0 !important
@include tools.layer('overrides')
margin: 0

.v-slider-track__fill
display: none
Expand Down
30 changes: 20 additions & 10 deletions packages/vuetify/src/components/VDataTable/VDataTable.sass
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,16 @@
.v-data-table-column--fixed,
.v-data-table__th--sticky
background: $table-background
position: sticky !important
left: 0
z-index: 1

@include tools.layer('overrides')
// Beat out relative on table > tbody > tr > td
// TODO: Use :where() for all those child combinators
// @scope would probably be even better but
// doesn't seem to be getting here any time soon
position: sticky

.v-data-table-column--last-fixed
border-right: 1px solid rgba(var(--v-border-color), var(--v-border-opacity))

Expand All @@ -99,8 +105,10 @@
.v-data-table__td
opacity: $data-table-loading-opacity

.v-data-table-group-header-row__column
padding-left: calc(var(--v-data-table-group-header-row-depth) * 16px) !important
@include tools.layer('overrides')
// Again, needs to beat all the child combinators
.v-data-table-group-header-row__column
padding-left: calc(var(--v-data-table-group-header-row-depth) * 16px)

.v-data-table-header__content
display: flex
Expand All @@ -119,11 +127,12 @@
width: $data-table-header-sort-badge-size
height: $data-table-header-sort-badge-size

.v-data-table-progress
> th
border: none !important
height: auto !important
padding: 0 !important
@include tools.layer('overrides')
.v-data-table-progress
> th
border: none
height: auto
padding: 0

.v-data-table-progress__loader
position: relative
Expand All @@ -148,8 +157,9 @@
grid-template-columns: repeat(2, 1fr)
min-height: var(--v-table-row-height)

&:not(:last-child)
border-bottom: 0 !important
@include tools.layer('overrides')
&:not(:last-child)
border-bottom: 0

.v-data-table__td-title
font-weight: VTable.$table-header-font-weight
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,39 +33,41 @@
position: relative
z-index: 1

&:not(&--variant-accordion)
> :not(:first-child):not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--before-active)
border-bottom-left-radius: 0 !important
border-bottom-right-radius: 0 !important
@include tools.layer('overrides')
&:not(&--variant-accordion)
> :not(:first-child):not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--before-active)
border-bottom-left-radius: 0
border-bottom-right-radius: 0

> :not(:first-child):not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--after-active)
border-top-left-radius: 0 !important
border-top-right-radius: 0 !important
> :not(:first-child):not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--after-active)
border-top-left-radius: 0
border-top-right-radius: 0

> :first-child:not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--before-active)
border-bottom-left-radius: 0 !important
border-bottom-right-radius: 0 !important
> :first-child:not(:last-child):not(.v-expansion-panel--active):not(.v-expansion-panel--before-active)
border-bottom-left-radius: 0
border-bottom-right-radius: 0

> :last-child:not(:first-child):not(.v-expansion-panel--active):not(.v-expansion-panel--after-active)
border-top-left-radius: 0 !important
border-top-right-radius: 0 !important
> :last-child:not(:first-child):not(.v-expansion-panel--active):not(.v-expansion-panel--after-active)
border-top-left-radius: 0
border-top-right-radius: 0

&--variant-accordion
> :first-child:not(:last-child)
border-bottom-left-radius: 0 !important
border-bottom-right-radius: 0 !important
&--variant-accordion
> :first-child:not(:last-child)
border-bottom-left-radius: 0
border-bottom-right-radius: 0

> :last-child:not(:first-child)
border-top-left-radius: 0 !important
border-top-right-radius: 0 !important
> :last-child:not(:first-child)
border-top-left-radius: 0
border-top-right-radius: 0

.v-expansion-panel-title--active
border-bottom-left-radius: initial
border-bottom-right-radius: initial
.v-expansion-panel-title--active
border-bottom-left-radius: initial
border-bottom-right-radius: initial

> :not(:first-child):not(:last-child)
border-radius: 0 !important
> :not(:first-child):not(:last-child)
border-radius: 0

&--variant-accordion
.v-expansion-panel-title__overlay
transition: 0.3s border-radius settings.$standard-easing

Expand Down
9 changes: 5 additions & 4 deletions packages/vuetify/src/components/VFab/VFab.sass
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@
align-items: flex-start

&--extended
.v-btn
// min-height: 56px
// min-width: 80px
border-radius: 9999px !important
@include tools.layer('overrides')
.v-btn
// min-height: 56px
// min-width: 80px
border-radius: 9999px

.v-fab__container
align-self: center
Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VList/VList.sass
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

#{$root}
min-height: $list-subheader-min-height + ($modifier * $list-subheader-min-height-multiplier)
padding-inline-start: calc(#{$base-padding} + var(--indent-padding)) !important
padding-inline-start: calc(#{$base-padding} + var(--indent-padding))

&--inset
--indent-padding: #{$list-subheader-inset-padding-start}
Expand Down
3 changes: 2 additions & 1 deletion packages/vuetify/src/components/VList/VListItem.sass
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@
--indent-padding: calc(var(--parent-padding) + var(--list-indent-size))

.v-list-group__items .v-list-item
padding-inline-start: calc(#{$base-padding} + var(--indent-padding)) !important
@include tools.layer('overrides')
padding-inline-start: calc(#{$base-padding} + var(--indent-padding))

.v-list-group__header:not(.v-treeview-item--activatable-group-activator).v-list-item--active
&:not(:focus-visible)
Expand Down
27 changes: 14 additions & 13 deletions packages/vuetify/src/components/VOverlay/VOverlay.sass
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,6 @@
top: 0
display: contents

.v-overlay-scroll-blocked
padding-inline-end: var(--v-scrollbar-offset)

&:not(html)
overflow-y: hidden !important

@at-root #{selector.append(html, &)}
position: fixed
top: var(--v-body-scroll-y)
left: var(--v-body-scroll-x)
width: 100%
height: 100%

.v-overlay
border-radius: inherit
display: flex
Expand Down Expand Up @@ -62,3 +49,17 @@

.v-overlay--scroll-blocked
padding-inline-end: var(--v-scrollbar-offset)

@include tools.layer('trumps')
.v-overlay-scroll-blocked
padding-inline-end: var(--v-scrollbar-offset)

&:not(html)
overflow-y: hidden

@at-root #{selector.append(html, &)}
position: fixed
top: var(--v-body-scroll-y)
left: var(--v-body-scroll-x)
width: 100%
height: 100%
6 changes: 4 additions & 2 deletions packages/vuetify/src/components/VTable/VTable.sass
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@
z-index: 2
> tr
> th
border-bottom: 0px !important
@include tools.layer('overrides')
border-bottom: 0px

.v-table--fixed-footer
> .v-table__wrapper
Expand All @@ -166,4 +167,5 @@
z-index: 1
> td,
> th
border-top: 0px !important
@include tools.layer('overrides')
border-top: 0px
6 changes: 4 additions & 2 deletions packages/vuetify/src/components/VTextarea/VTextarea.sass
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
position: absolute
top: 0
left: 0
height: 0 !important
min-height: 0 !important
pointer-events: none

@include tools.layer('overrides')
height: 0
min-height: 0

&--no-resize
.v-field__input
resize: none
Expand Down
14 changes: 8 additions & 6 deletions packages/vuetify/src/components/VTooltip/VTooltip.sass
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
transition-property: opacity, transform
overflow-wrap: $tooltip-overflow-wrap

&[class*="enter-active"]
transition-timing-function: settings.$decelerated-easing
transition-duration: $tooltip-transition-enter-duration
@include tools.layer('overrides')
.v-tooltip > .v-overlay__content
&[class*="enter-active"]
transition-timing-function: settings.$decelerated-easing
transition-duration: $tooltip-transition-enter-duration

&[class*="leave-active"]
transition-timing-function: settings.$accelerated-easing
transition-duration: $tooltip-transition-leave-duration
&[class*="leave-active"]
transition-timing-function: settings.$accelerated-easing
transition-duration: $tooltip-transition-leave-duration
Loading

0 comments on commit f7123c6

Please sign in to comment.