Skip to content
Merged
8 changes: 8 additions & 0 deletions packages/docs/src/pages/en/features/sass-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ Color packs are handy for quickly applying a color to a component but mostly unu
);
```

```ts { resource="src/plugins/vuetify.ts" }
export default createVuetify({
theme: {
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`.
Expand Down
30 changes: 26 additions & 4 deletions packages/docs/src/pages/en/features/theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,30 @@ export default createVuetify({
})
```

## Theme layers

The `layers` option can be used to enable a [css cascade layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) for the theme:

```ts { resource="src/plugins/vuetify.ts" }
export default createVuetify({
theme: {
layers: true,
},
})
```

which generates the theme layer with two sub-layers (background and foreground):

```css
@layer vuetify.theme {
:root { /* ... */ }
@layer background { /* ... */ }
@layer foreground { /* ... */ }
}
```

`$layers` should also be enabled in SASS for theme colors to override component defaults correctly, see [SASS variables](/features/sass-variables/#enabling-css-cascade-layers) for more information.

## Theme object structure

```ts
Expand Down Expand Up @@ -361,10 +385,8 @@ Content-Security-Policy: script-src 'self' 'nonce-dQw4w9WgXcQ'
Content-Security-Policy: style-src 'self' 'nonce-dQw4w9WgXcQ'
```

```ts
// src/plugins/vuetify.js

import {createVuetify} from 'vuetify'
```ts { resource="src/plugins/vuetify.ts" }
import { createVuetify } from 'vuetify'

export const vuetify = createVuetify({
theme: {
Expand Down
11 changes: 11 additions & 0 deletions packages/vuetify/src/composables/__tests__/theme.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,15 @@ describe('createTheme', () => {
expect(css).not.toContain('.text-primary')
expect(css).not.toContain('.border-primary')
})

it('should generate layers', async () => {
const theme = createTheme({ layers: true })

theme.install(app)

const stylesheet = document.getElementById('vuetify-theme-stylesheet')
const css = stylesheet!.innerHTML

expect(css).toContain('@layer vuetify.theme {')
})
})
25 changes: 23 additions & 2 deletions packages/vuetify/src/composables/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export type ThemeOptions = false | {
stylesheetId?: string
scope?: string
unimportant?: boolean
layers?: boolean
}
export type ThemeDefinition = DeepPartial<InternalThemeDefinition>

Expand All @@ -58,6 +59,7 @@ interface InternalThemeOptions {
scoped: boolean
unimportant: boolean
utilities: boolean
layers?: boolean
}

interface VariationsOptions {
Expand Down Expand Up @@ -419,10 +421,29 @@ export function createTheme (options?: ThemeOptions): ThemeInstance & { install:
}
}

lines.push(...bgLines, ...fgLines)
if (parsedOptions.layers) {
lines.push(
'@layer background {\n',
...bgLines.map(v => ` ${v}`),
'}\n',
'@layer foreground {\n',
...fgLines.map(v => ` ${v}`),
'}\n',
)
} else {
lines.push(...bgLines, ...fgLines)
}
}

let final = lines.map((str, i) => (i === 0 ? str : ` ${str}`)).join('')
if (parsedOptions.layers) {
final =
'@layer vuetify.theme {\n' +
lines.map(v => ` ${v}`).join('') +
'\n}'
}

return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('')
return final
})

const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`)
Expand Down
4 changes: 3 additions & 1 deletion packages/vuetify/src/styles/generic/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}

@if (settings.$color-pack) {
@include tools.layer('colors') {
@include tools.layer('theme.background') {
@each $color_name, $color_value in colors.$shades {
.bg-#{$color_name} {
@include background-color($color_value);
Expand Down Expand Up @@ -55,7 +55,9 @@
}
}
}
}

@include tools.layer('theme.foreground') {
@each $color_name, $color_value in colors.$shades {
.text-#{$color_name} {
@include text-color($color_value);
Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/styles/generic/_layers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

@if (settings.$layers) {
@layer vuetify {
@layer reset, transitions, base, components, overrides, colors, theme, utilities;
@layer reset, transitions, base, components, overrides, theme.background, theme.foreground, utilities;
}
}