Deciphering the Sequence of Applying CSS Classes in Vue.js

Seeking assistance in understanding how to control the ordering of a component's root element CSS class and any CSS class bound from the parent calling the component.

View this fiddle for illustration: https://jsfiddle.net/cicsolutions/b6rnaw25/

If a component has a class on its root element and that class is a string, Vue's class binding places the class at the beginning of the resulting bound class list. This logic follows as the component sets the base CSS class and users can customize styles by adding classes to the HTML element. Vue then binds/joins these classes together.

In cases where a dynamic CSS class (not a static string) is used, Vue positions the component's root element class at the end of the bound class list.

I am developing a component for wider use, aiming to set my component class on the root element with the option for others to override styles by simply adding their class to the component tag.

The root element class needs to be dynamic, requiring the utilization of an array or object for class binding.

Why does Vue place the component's root CSS class at the beginning for static classes and at the end for dynamic classes? While it may seem peculiar, there could be intentional reasons behind it that are not clear at first glance.

Regardless, how can I ensure that my component's root element class always appears first in the resulting bound class list when it needs to be a dynamic class?


        Vue.directive('bound-class', (el) => {
          const boundClass = el.attributes.class.nodeValue
          const boundClassPrintout = document.createElement('div')
          boundClassPrintout.innerHTML = 'Resulting Bound Class: ' + boundClass
          el.appendChild(boundClassPrintout)
        });

        // STATIC CSS CLASS -> becomes 1st class in the bound class list (expected)
        Vue.component('string-test', {
          template: `<div class="string-class" v-bound-class><slot></slot></div>`
        });

        // DYNAMIC CSS CLASS -> becomes last class in the bound class list (unexpected)
        Vue.component('array-test', {
          template: `<div :class="['array-class']" v-bound-class><slot></slot></div>`
        });

        // DYNAMIC CSS CLASS -> becomes last class in bound class list (unexpected)
        Vue.component('object-test', {
          template: `<div :class="{ 'object-class': true }" v-bound-class><slot></slot></div>`
        });

        new Vue({
          el: "#app",
          computed: {
            vueVersion() {
              return Vue.version
            }
          }
        })
      

        body {
          background: #20262E;
          padding: 20px;
        }

        #app {
          background: #fff;
          border-radius: 4px;
          padding: 20px;
        }

        h2 {
          margin-bottom: 0.75rem;
        }
      

        <link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet"/>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

        <div id="app">
          <h2>Vue version: {{ vueVersion }}</h2>
          <string-test class="p-2 mb-2 border">Root class (string-class) at beginning (expected)</string-test>
          <array-test class="p-2 mb-2 border">Root class (array-class) at end (unexpected)</array-test>
          <object-test class="p-2 mb-2 border">Root class (object-class) at end (unexpected)</object-test>
        </div>
      

Answer №1

It seems that Vue may not have a specific reason for inserting static classes first; it could be just following the order of input parameters in the renderClass function.

The sequence of rule sets in CSS files is important, unlike the order of class names in the class attribute of elements. This order has nothing to do with the cascade concept, which involves child elements inheriting styles from their parents. It's possible you might have confused this with the order of declarations within a block or an inline style, where order does matter:

<p class="red blue">
    In the class attribute above, the order doesn't affect the outcome.
    If there are conflicting class styles, the one defined last will take precedence.
</p>

<p class="blue red">
    Despite the change in class order, this paragraph will look the same as the previous one.
</p>

<p style="color: red; color: blue">
    The order matters here. The text color will be blue.
</p>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

TS2531: There is a potential for the object to be 'null'. Ionic framework with Vue.js

I am facing a challenge with the following Error message: TS2531: Object is possibly 'null'. This error arises due to the following code snippet: let aNewList = []; aNewList = this.Listen.filter( function(item) { return item !== ID }); The setu ...

Implementing a fixed div with jQuery scrolling

I need the left div to stay in sync with the scrolling content. However, there is a challenge because this div is taller than the screen. I want the user to be able to see the bottom of the left div when they reach the bottom of the page. My solution invo ...

Push information into MongoDB without the need to make changes to the entire entry within the MEAN stack

I have a MEAN Stack single-page application up and running for managing exams. The schema/model I have for an exam (or Klausur in German) looks like this: var KlausurSchema = new Schema( { name: String, semester: String, krankm ...

Applying a dual background effect with one background repeating from the center using CSS3

I am trying to achieve a unique effect with CSS3 backgrounds. I want the second background image to start repeating from the middle of the screen down, rather than from the top. Below is my CSS code: body { background: url('../img/carbon_fibre.png ...

I am facing difficulties retrieving the JSON object returned from the Express GET route in Angular

After setting up an express route, the following JSON is returned: [{"_id":"573da7305af4c74002790733","postcode":"nr22ry","firstlineofaddress":"20 high house avenue","tenancynumber":"12454663","role":"operative","association":"company","hash":"b6ba35492f3 ...

Utilizing the not(:last-child) selector effectively within a list structure

I need help targeting all elements except the last one in a ul/li list with CSS. The structure looks like this: <ul class="xxx"> <li> <figure> [different divs / content] </figure> </li> <li> <fig ...

Utilizing Vue.js to pass a slot to a customized Bootstrap-Vue Table component

I am currently in the process of developing a wrapper for the bootstrap-vue Table component. This particular component utilizes slots to specify cell templates, similar to the following example: <b-table :items="itemsProvider" v-bind="options"> ...

Vue components not responding to TailwindCSS breakpoints as expected

After successfully integrating Tailwind into my Vue project and ironing out the initial kinks, I am now facing a roadblock. Despite having code completion in VS Code, I am unable to utilize breakpoints within my project. <div class="container mx-auto"& ...

Striking new design for bootstrap 3 datepicker with a unique custom theme - stunning appearance

After purchasing a custom Metro theme from the John Papa AngularJS/Breeze courses on Pluralsight, everything was running smoothly until I attempted to integrate a Bootstrap 3 date picker into the mix. Unfortunately, right off the bat, it looked quite messy ...

Strange spacing issues with inline-block elements and struggling to vertically center content within them

I feel like I'm losing my mind trying to figure this out... any help would be greatly appreciated. There are three divs on the page that need to sit on a single line. They must be square with rounded corners, so setting width and height is necessary ...

Building a jQuery DataTable with SQL Server and JSON Integration

I am having trouble figuring out what I am doing incorrectly. Could it be that the format I am using for executing an ajax call and returning JSON is not correct? My aim is to use JSON data to populate a DataTable. Although I have previously done somethin ...

Create text that alternates between blinking and changing content simultaneously

I'm currently working on a website and I am curious about how to achieve the effect of making text blink and change content simultaneously, similar to what is seen on this particular website . Sorry for not being more specific in my question. Thank yo ...

javascript monitoring numerous socket channels for echoes

Currently, I am in the process of developing a chat application. On the server side, I am utilizing: php, laravel 5.4, and pusher. On the client side, I have incorporated vue.js along with laravel-echo. Initially, I successfully created a "public chat roo ...

Is there a way to incorporate a website into a pop-up window for a Chrome extension?

Hey there! I'm currently working on developing a Google Chrome extension that will feature a button in the browser. When this button is clicked, it should open up a bubble popup displaying content from this site: . However, as a newcomer to this proce ...

The term 'sequelize' is missing its definition - it involves Sequelize and consign

Just starting out in the world of Node.js. I'm currently working on integrating Sequelize into a basic application with Consign. In my "config/db.js" file: var Sequelize = require('sequelize'); var sequelize = new Sequelize('test&ap ...

Using Unicode JSON in Laravel blade to pass data to React components, encountering an issue with JSON parsing

I currently have a JSON object stored in the database: { "ui": {}, "title": "Hola mundo 2", "values": {}, "properties": {}, "description": "descripcion" } Within the Laravel controller, ...

Regular expression for eliminating the local path from a website address

I am facing a scenario where different formats of relative paths can occur, such as: const URL1 = "./hello-world" const URL2 = "../hello-world" const URL3 = "../../hello-world" const URL4 = "../../../hello-world" con ...

Associating a mouse click with elements within a repetitious function

Currently, I am importing children of element with ID #parentEle, creating a duplicate of each child and adding it to an array with a new ID - #eleCopy(i). I am facing an issue where I am trying to implement a click function on the original imported objec ...

What is the trick to getting an accordion to expand when hovering, rather than when clicking?

Can the accordion be set to expand when hovering instead of clicking? Also, how can a different action be triggered on click? LATEST I was specifically referring to using the jQuery UI accordion widget for this functionality. ...

Changing a PHP object into an array

I've searched for solutions on various platforms, but my situation presents a unique challenge. In my PHP charts factory, I am passed an array of strings like: $charts = ['SomeChart', 'SomeOtherChart', 'AndAnotherChart' ...