Class & Style Attributes
Use htmlAttrs and bodyAttrs to set attributes on <html> and <body>. Class and style values can be strings, arrays, or objects.
The class and style attributes accept strings, arrays, and objects for static or reactive values.
Static classes and styles
If your classes or styles aren't going to change, you can provide them as a string.
import { useHead } from 'unhead'
// useHead: /docs/head/api/composables/use-head
useHead(unheadInstance, {
htmlAttrs: {
class: 'my-class my-other-class',
style: 'background-color: red; color: white;'
}
})
import { useHead } from 'unhead'
useHead(unheadInstance, {
bodyAttrs: {
class: 'my-class my-other-class',
style: 'background-color: red; color: white;'
}
})
Array values
Use arrays to supply classes or declarations without joining them into a string:
import { useHead } from 'unhead'
useHead(unheadInstance, {
htmlAttrs: {
class: [
'my-class',
'my-other-class'
],
style: [
'background-color: red',
'color: white'
],
}
})
Dynamic classes and styles
Use an object or array when class values need to update reactively or merge with another entry.
Conditional classes
With the object form, each key is a class name and its value controls whether Unhead includes that class.
import { useHead } from 'unhead'
const colorMode = useColorMode()
useHead(unheadInstance, {
htmlAttrs: {
class: {
// rendered when colorMode is dark
dark: () => colorMode.value === 'dark',
// rendered when colorMode is not dark
light: () => colorMode.value !== 'dark'
}
}
})
Reactive styles
Style objects can contain reactive values too:
import { useHead } from 'unhead'
const colorMode = useColorMode()
useHead(unheadInstance, {
bodyAttrs: {
style: {
// conditional style that only applies when darkMode is true
'background-color': () => colorMode.value === 'dark' ? 'rgba(0, 0, 0, 0.9)' : false,
// reactive style that always applies with current value
'font-size': () => fontSize.value,
}
}
})
Merging classes across entries
When several entries set classes on the same element, Unhead merges them into a single tag and combines all class names. Conflicting utility classes, such as two Tailwind background colors from app.vue and a page, are kept side by side because Unhead does not know they conflict.
// app.vue
useHead(unheadInstance, { bodyAttrs: { class: 'bg-red-500' } })
// pages/index.vue
useHead(unheadInstance, { bodyAttrs: { class: 'bg-green-500' } })
// <body class="bg-red-500 bg-green-500">
Use the tags:afterResolve hook with a class merge tool such as tailwind-merge to resolve conflicts yourself.
import { twMerge } from 'tailwind-merge'
import { injectHead } from 'unhead/vue'
const head = injectHead()
head.hooks.hook('tags:afterResolve', ({ tags }) => {
for (const tag of tags) {
if (tag.tag !== 'bodyAttrs' || !tag.props.class)
continue
// resolved classes are an iterable of class names
const merged = twMerge([...tag.props.class].join(' ')).trim()
tag.props.class = merged ? merged.split(/\s+/) : []
}
})
// <body class="bg-green-500">
See Also
- useHead() API: Full API reference
- Build Plugins: Build-time optimizations