DEV Community

Cover image for How to avoid empty class in Vue with null
Samantha Ming
Samantha Ming

Posted on • Updated on • Originally published at samanthaming.com

How to avoid empty class in Vue with null

Alt Text

Instead of passing an empty string, which can lead to an empty class in the DOM output. In your ternary operator, you can return "null". This will ensure no empty class in the DOM 🌟

<!-- ❌ -->
<div :class="isBold ? 'bold' : ''">
<!-- <div class> -->

<!-- βœ… -->
<div :class="isBold ? 'bold' : null">
<!-- <div> -->

Comparing Empty String '' vs null

Let's dig into the above example, and see a more complete picture of what's going on.

Scenario 1: Using Empty String ''

We are using a ternary operator to conditional set the appropriate class depending on if isBold is truthy or falsy. In this example, we're saying that if isBold is truthy, it will set the class to be bold. If it's falsy, it will return an empty string ''. This syntax :class is short for v-bind:class.

<div :class="isBold ? 'bold' : ''"></div>
data() {
  return {
    isBold: false
  }
}

This will render:

<div class></div>
<!-- 😱 Yikes, empty class -->

And if isBold is true, it will render:

<div class="bold"></div>

Scenario 2: Using null

Alright, let's see what happens if we assign null as the value for our class.

<div :class="isBold ? 'bold' : null"></div>
data() {
  return {
    isBold: false
  }
}

This will render:

<div></div>
<!-- βœ… Nice, no empty class -->

And if isBold is true, it will render:

<div class="bold"></div>

Scenario 3: using undefined

By the way, undefined would also work πŸ‘

<div :class="isBold ? 'bold' : undefined"></div>
<div></div>
<!-- βœ… Nice, no empty class -->

Falsy Values

Just a quick reminder that these are the falsy values in JavaScript. So if isBold is any of these values, it will return the falsy condition of the ternary operator.

false
undefined
null
NaN
0
"" or '' or `` (empty string)

To read more about this topic, you can check out my previous post, JS Essentials: Falsy Values.

Refactoring with Object Syntax

For my simple example, it's probably way better to use the Object Syntax like this:

<div :class="{ bold: isBold }"></div>

I guess a better example of using a ternary operator would be for setting multiple classes.

<div :class="isActive ? 'underline bold' : null"></div>

Tangent: When I'm creating tidbits, I always try to keep things as simple as I can. And one way to do it is to reduce as much visual noise as possible. So my examples can sometimes be overly simplified in hope of the reader being able to grasp the concept immediately without doing much processing. A big inspiration that I follow is from this book, Don't Make Me Think. Okay enough tangent, let's get back to the main course! πŸ˜†

Using && to set class

Let's explore another scenario and see if it works.

<div :class="isBold && 'bold'"></div>

&& is not just a logical operator that results in a boolean value. It can actually produce a value. So it's saying if isBold is truthy then return bold. However, if isBold is falsy, then return the value of isBold.

Emphasis on the last point -- It will return the value of isBold. So our original problem of having an empty class can still exist depending on what the value of isBold is. Let's look at some examples.

Example A: isBold equals false

<div :class="isBold && 'bold'"></div>

This will still render the empty class 😱

<div class></div>

Example B: isBold equals null

<div :class="isBold && 'bold'"></div>

Since isBold is null, the empty class is gone πŸ‘

<div></div>

There's nothing wrong with && -- it is in fact doing its job. It's just that we need a specific return value. In other for us NOT to render an empty class, we have to pass null or undefined. Any other falsy value just won't work. Because this can be so easily missed, I much prefer the more explicit ternary operator OR simply the object syntax πŸ‘

Is Empty Class Attribute Bad?

I tried checking this with the W3C Markup Validation Service, and both syntaxes do indeed pass.

<!-- Pass -->
<div class>...</div>

<!-- Pass -->
<div>...</div>

And diving into the HTML Standard: Empty attribute syntax, it doesn't seem like it disallows empty attribute.

BUT...

But the valid-ness does NOT apply to id. Because empty id is considered invalid.

<!-- Fail -->
<div id>...</div>

<!-- Fail -->
<div id="">...</div>

<!-- Pass -->
<div id="name">...</div>

❌ Error: An ID must not be the empty string.

Conclusion

Since the empty class is considered valid and the specs are not against it, this all comes to your stylistic choice. It's your codebase and you can decide how you want to handle it. If you want to keep your HTML output clean, then you can pass null to your Vue ternary operator. If it doesn't matter to you, then forget it. There's no incorrect answer here, it all depends on what you prefer πŸ‘

Community Input

@kiwi_kaiser: _(What's wrong with Empty classes?__ Noise in the code. Makes it bigger, the user has to download more and search machines have to work harder to get the important information out of the website.

@felipperegazio: Just a quick comment about something to consider: CSS :not([class]) selector wont be applied for an element with class="". I mean: an element with class="" wont be targeted by :not([class]) - which is right because the attribute class is there.

This could lead to misconceptions and that's why I consider that kind of selector a bad practice. Anyway, some developers use this selector to validate whether the element has classes or not, which became especially dangerous when using Vue, so your post subject is also useful to prevent bugs in this situation.

Resources


Thanks for reading ❀
To find more code tidbits, please visit samanthaming.com

🎨Instagram 🌟Twitter πŸ‘©πŸ»β€πŸ’»SamanthaMing.com

Top comments (6)

Collapse
 
felipperegazio profile image
Felippe Regazio • Edited

Pretty cool Samantha, thanks! Just a quick comment about something to consider: CSS :not([class]) selector wont be applied for an element with class="". I mean: an element with class="" wont be targeted by :not([class]) - which is right because the attribute class is there.

This could lead to misconceptions and thats why i consider that kind of selector a bad practice. Anyway, some developers use this selector to validate whether the element has classes or not, which became specially dangerous when using Vue, so your post subject is also useful to prevent bugs in this situation.

Collapse
 
samanthaming profile image
Samantha Ming • Edited

Oh, cool! What a fantastic point you made πŸ‘ Thanks for sharing it, definitely need to add it to my notes πŸ”₯

Collapse
 
chiubaca profile image
Alex Chiu

What a weird quirk... feels like Vue shouldn't create an empty class on any falsey value . I had a quick look to see if there is bug for this but the closest thing I found was this closed issue - github.com/vuejs/vue/issues/10791

I don't really understand the closing comment

"class and style have a proper handling and, differently from other attributes, when set to undefined, they keep the empty attribute on the element, probably for performance reasons"

πŸ€·β€β™‚οΈ

Collapse
 
samanthaming profile image
Samantha Ming

I guess because it isn't considered invalid, they left it alone. But they do prevent empty id ...since that will throw an error. So I guess that's good then πŸ˜†

Collapse
 
vaibhavkhulbe profile image
Vaibhav Khulbe

Such a great post! I never thought null would be so useful πŸ”₯

Collapse
 
samanthaming profile image
Samantha Ming

I know right! My co-worker showed me this and now I'm just passing on the knowledge! Glad you found the post helpful πŸ˜„