Post cover

How to Show/Hide Elements in Vue

Posted November 3, 2021

Hiding and showing elements on a web page is an often occurring UI-related task. You might want to toggle the visibility of some detail sections, tooltips, and more.

In this post, you'll learn how to hide elements on a web page using 3 approaches provided by Vue:

  • When the element is completely removed from DOM using v-if;
  • When the element is hidden using display: none applied by v-show;
  • Applying the visibility: hidden using the :class binding.

Before I go on, let me recommend something to you.

Using Vue composition API is fun... but sometimes challenging. Take "Vue 3 Composition API" course by Vueschool to become proficient in Vue composition and reactivity in just a few weekends!

1. Hiding using v-if

v-if is a built-in Vue directive that accepts boolean values:


<div v-if="value">I am an element</div>

v-if deals withing showing/hiding the element as follows:

A) If the value supplied to v-if is true (or generally a truthy value), then the element is inserted into the DOM;

B) Otherwise, if the value supplied to v-if is false (or generally a falsy value), then the element is not inserted into the DOM.

Let's consider the following example:


<template>
<div v-if="value1">I'm rendered!</div>
<div v-if="value2">I'm not rendered!</div>
</template>
<script>
export default {
data() {
return {
value1: true,
value2: false
}
}
};
</script>

Open the demo.

When the above component runs, here's what HTML content is inserted into the web page:


<div>I'm rendered!</div>

The first element is rendered because v-if="value1" was supplied with a true value. The second element, however, isn't rendered into the DOM because v-if="value2" was supplied with a false.

In simple words, v-if directive allows you to show or hide the element just by inserting or not the element into the DOM. Brutally simple.

1.1 When to use v-if

When v-if directive is assigned with false, Vue also doesn't initialize the event listeners on the element, even if you explicitly use the event directives.

v-if toggling is relatively expensive (since each time you change v-if value the element is inserted/removed from DOM, as well event listeners are initialized/uninitialized) compared to v-show (presented in the next section). But it has a low initialization cost if the element is initially hidden.

You'd use v-if on the elements which visibility isn't toggled too often and is initially hidden. For example, to show/hide a section having detailed information about an entity.

Challenge: would v-if render the element if assigned with 0? What about '0'?

2. Hiding using v-show

Often it's useful to keep the element present in the DOM, but have it visually hidden using CSS styles.

v-show is a built-in directive that shows or hides the element visually:


<div v-show="value">I am an element</div>

v-show deals with showing the element as follows:

A) If the value supplied to v-show is true (or truthy), then the element is visible;

B) Otherwise, if the value supplied to v-show is false (or falsy), then the element is hidden, but still rendered in the DOM.

Let's look at the following example:


<template>
<div v-show="value1">I'm visible!</div>
<div v-show="value2">I'm hidden!</div>
</template>
<script>
export default {
data() {
return {
value1: true,
value2: false
}
}
};
</script>

Open the demo.

When you run the above component both elements are rendered into the DOM:


<div>I'm visible!</div>
<div style="display: none;">I'm hidden!</div>

The first element is visible on the screen. However, the second is hidden because Vue applies display: none inline style, thanks to v-show="false".

display: none applied to an element makes the element disappear completely.

Challenge: how can you implement in Vue a button that toggles the display of an element? Share your solution in a comment!

2.1 When to use v-show

v-show, when assigned with false, applies display: none inline style and hides the element visually and makes almost no modifications to the DOM.

Thus toggling the element's visibility using v-show is relatively cheap (compared to v-if described above), so you might use this directive with an element which visibility is toggled often.

3. Hiding but keeping the space

What if you need to hide the element's content while keeping the space it occupies? The CSS style that hides the element content but keeps its space is visibility: hidden.

Unfortunately, you cannot use v-show directive because it applies only display: none style.

But a viable solution is to use :class binding, which is pretty flexible in Vue. When the object literal { className: boolValue } is assigned to the :class, Vue applies the "className" as a class to the element if boolValue is true.

Let's create a CSS class invisible having the visibility: hidden style. Then, using the :class binding and an object literal you can apply the invisible class to an element:


<template>
<div :class="{ invisible: !value1 }">I'm visible!</div>
<div :class="{ invisible: !value2 }">Only my space is visible!</div>
<div>Dummy text</div>
</template>
<script>
export default {
data() {
return {
value1: true,
value2: false
}
}
};
</script>
<style>
.invisible {
visibility: hidden;
}
</style>

Open the demo.

Open the demo you'd see the elements I'm visible and Dummy text, and a space in between the two — the hidden second element.

The above example renders the HTML content:


<div class="">I'm visible!</div>
<div class="invisible">Only my space is visible!</div>
<div>Dummy text</div></div>

<div :class="{ invisible: !value2 }">Only my space is visible!</div> applies the invisible class to the element because value2 is false (I know the negation here is confusing!).

Note that you can also hide the element by using opacity: 0, or even offset the element out of the viewport using position: absolute; left: -9999px. Just create the appropriate CSS class and then toggle it using :class.

4. Conclusion

Vue gives you a bunch of good ways to hide the element on the screen.

When using v-if="false" the element isn't rendered at all in the DOM.

When using v-show="false" the element is rendered in the DOM, however, Vue applies the inline style display: none that hides the element completely.

Also, do not forget about the powerful :class binding if you'd like more visibility customization.

To hide the element but keep its space use :class="{ invisible: !value }" to assign invisible class (which has visibility: hidden style applied to it).

Like the post? Please share!

Dmitri Pavlutin

About Dmitri Pavlutin

Software developer and sometimes writer. My daily routine consists of (but not limited to) drinking coffee, coding, writing, overcoming boredom 😉. Living in the sunny Barcelona. 🇪🇸