Class and Style Bindings
A common need for data binding is manipulating an element’s class list and inline styles.
Since class
and style
are both attributes, you can use v-bind
to assign them a string value dynamically, much like with other attributes.
However, trying to generate those values using string concatenation can be annoying and error-prone.
For this reason, Vue provides special enhancements when v-bind
is used with class
and style
.
In addition to strings, the expressions can also evaluate to objects
or arrays
.
Binding HTML Classes
Section titled “Binding HTML Classes”Watch Free Video Lesson on Class and Style Bindings From Vue School
Binding to Objects
Section titled “Binding to Objects”You can pass an object to :class
(short for v-bind:class
) to dynamically toggle classes:
<div :class="{ active: isActive }"></div>
The above syntax means the presence of the active
class will be determined by the truthiness of the data property isActive
.
You can have multiple classes toggled by having more fields in the object. In addition, the :class
directive can also co-exist with the plain class
attribute. So given the following state:
data() {return { isActive: true, hasError: false}}
The template:
<div class="static":class="{ active: isActive, 'text-danger': hasError }"></div>
And the rendered HTML will be:
<div class="static active"></div>
When isActive
or hasError
changes, the class list will be updated accordingly.
For example, if hasError
becomes true
, the class list will become "static active text-danger"
.
The bound object doesn’t have to be inline:
data() {return { classObject: { active: true, 'text-danger': false }}}
<div :class="classObject"></div>
This will render the same result. You can also bind to a computed property that returns an object. This is a common and powerful pattern:
data() { return { isActive: true, error: null } }, computed: { classObject() { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } } }
<div :class="classObject"></div>
Binding to Arrays
Section titled “Binding to Arrays”You can bind to an array to apply a list of classes:
data() {return { activeClass: 'active', errorClass: 'text-danger'}}
<div :class="[activeClass, errorClass]"></div>
Which renders:
<div class="active text-danger"></div>
If you want to toggle a class in the list conditionally, you can do it with a ternary expression:
<div :class="[isActive ? activeClass : '', errorClass]"></div>
This will always apply errorClass
, but activeClass
will only be applied when isActive
is truthy.
However, this can be a bit verbose if you have multiple conditional classes. That’s why it’s also possible to use the object syntax inside arrays:
<div :class="[{ active: isActive }, errorClass]"></div>
With Components
Section titled “With Components”Prerequisites
- Basic understanding of components. Feel free to skip it and come back later.
When you use the class
attribute on a custom component, those classes will be added to the component’s root element. Existing classes on that element will not be overwritten.
For example, if you have a component named MyComponent
with the following template:
<p class="foo bar">Hi!</p>
Then add some classes when using it:
<MyComponent class="baz"></MyComponent>
The final rendered HTML will be:
<p class="foo bar baz boo">Hi!</p>
The same rule applies when :class
is used on a custom component:
<MyComponent :class="{ active: isActive }"></MyComponent>
When isActive
is truthy, the rendered HTML will be:
<p class="foo bar active">Hi!</p>
If your component has multiple root elements, you would need to define which element will receive this class. You can do this using the $attrs
component property:
<!-- MyComponent template using $attrs --><p :class="$attrs.class">Hi!</p><span>This is a child component</span>
<MyComponent class="baz"/>
The final rendered HTML will be:
<p class="baz">Hi!</p><span>This is a child component</span>
You can learn more about component attribute inheritance in Fallthrough Attributes section.
Binding Inline Styles
Section titled “Binding Inline Styles”Binding to Objects
Section titled “Binding to Objects”:style
supports binding to JavaScript object values - it corresponds to an HTML element’s style
property:
data() {return { activeColor: 'red', fontSize: 30}}
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Although camelCase keys are recommended, :style
also supports kebab-cased CSS property keys (corresponds to how they are used in actual CSS) - for example:
<div :style="{ 'font-size': fontSize + 'px' }"></div>
It is often a good idea to bind to a style object directly so that the template is cleaner:
data() {return { styleObject: { color: 'red', fontSize: '13px' }}}
<div :style="styleObject"></div>
Again, object style binding is often used in conjunction with computed properties that return objects.
:style
directives can also coexist with regular style attributes, just like :class
.
<h1 style="color: red" :style="'font-size: 1em'">hello</h1>
hello
Binding to Arrays
Section titled “Binding to Arrays”You can bind :style
to an array of multiple style objects. These objects will be merged and applied to the same element:
<div :style="[baseStyles, overridingStyles]"></div>
Auto-prefixing
Section titled “Auto-prefixing”When you use a CSS property that requires vendor prefixes in :style
, for example transform
, Vue will automatically add the appropriate prefixes to the applied styles.
Vue does this by checking at runtime to see which style properties are supported in the current browser. If the browser doesn’t support a particular property then various prefixed variants will be tested to try to find one that is supported.
Multiple Values
Section titled “Multiple Values”You can provide an array of multiple (prefixed) values to a style property, for example:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
This will only render the last value in the array which the browser supports. In this example, it will render display: flex
for browsers that support the unprefixed version of flexbox.