Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS styles not being applied to HTML within a Vue Component

I am trying to create a rotating text animation using Vue.js and I used this CodePen as inspiration.

  • I got all the HMTL elements properly in place (i.e., as in the CodePen mentioned). In short:

    • each word is formed of several <span> elements, each containing one letter.
    • following a specific time interval, each <span> that holds a letter gets applied an .in and .out CSS class. This goes on indefinitely.
    • here is what it looks like in the DOM:

      enter image description here

  • the problem is that no matter what CSS selectors I use, I can't target the .in and .out classes, unless I do it via Developer Tools in Chrome:

    • original output:

      enter image description here

    • output after I added the classes in Developer Tools:

      enter image description here

Here is the bare minimum code of my Vue Component:

<template>
    <div id="app-loading">  
        <div class="words">
            <span v-for="setting in settings" v-html="setting.lettersHTML" :id="setting.id" class="word"></span>    
        </div>
    </div>
</template>


<script>
    export default {
        data() {
            return {
                settings: [
                    { word: 'WordOne', id: 1, lettersArray: null, lettersHTML: null },
                    { word: 'WordTwo', id: 2, lettersArray: null, lettersHTML: null }
                ],
                currentWord: 1
            }
        },

        created() {
            this.splitLetters();
        },

        mounted() {
            setInterval(this.changeWord, 1500);
        },

        methods: {
            splitLetters() {
                this.settings.forEach((setting) => {
                    let letters = [];
                    for (let i = 0; i < setting.word.length; i++) {
                        let letter = `<span class="letter">${ setting.word.charAt(i) }</span>`;
                        letters.push(letter);
                    }
                    setting.lettersArray = letters;
                    setting.lettersHTML = letters.join('');
                });
            },

            changeWord() {
                let current = document.getElementById(this.currentWord).getElementsByTagName('span');
                let next = (this.currentWord == this.settings.length) ? document.getElementById(1).getElementsByTagName('span') : document.getElementById(this.currentWord + 1).getElementsByTagName('span');
                // Animate the letters in the current word.
                for (let i = 0; i < current.length; i++) {
                    this.animateLetterOut(current, i);
                }
                // Animate the letters in the next word.
                for (let i = 0; i < next.length; i++) {
                    this.animateLetterIn(next, i);
                }
                this.currentWord = (this.currentWord == this.settings.length) ? 1 : this.currentWord + 1;
            },

            animateLetterOut(current, index) {
                setTimeout(() => {
                    current[index].className = 'letter out';
                }, index * 300);
            },

            animateLetterIn(next, index) {
                setTimeout(() => {
                    next[index].className = 'letter in';
                }, 340 + (index * 300));
            }
        }
    }
</script>


<style lang="scss" scoped>
    #app-loading {
        font-size: 4rem;
    }

    .words, .word {
        border: 1px solid rosybrown;
    }

    .letter {
        text-decoration: underline; // Not working.
    }

    .letter.in {
        color: red; // Not working.
    }

    .letter.out {
        color: blue; // Not working.
    }
</style>

What goes wrong that prevents these classes from being applied?

like image 398
Mihai Avatar asked Jan 18 '18 22:01

Mihai


People also ask

How do I add styles to Vue component?

In Vue. js, we can add an inline style to our element by binding the style attribute in the HTML tag. For reference, :style is shorthand for v-bind:style . Inline styling can be done in two ways: using object syntax or array syntax.

How do I use style CSS in Vue?

Adding CSS classes in Vue We should apply the button CSS classes to the <button> in our ToDoForm component. Since Vue templates are valid HTML, this is done in the same way to how you might do it in plain HTML — by adding a class="" attribute to the element.

Does Vue use HTML and CSS?

Vue. js (or simply Vue) is a lightweight, JavaScript framework for building reactive web user interfaces. Vue extends standard HTML and CSS to create a suite of powerful tools for building the front end of interactive web applications.

How do I add external CSS to Vue?

Include CSS file in one component If you want to include the external CSS file in only one component you can import it in the <style></style> tag. For example, we want to include Bootstrap 4 CSS file in a single component. It will only work for that component.


1 Answers

You're using v-html, but that doesn't work with scoped styles.

DOM content created with v-html are not affected by scoped styles, but you can still style them using deep selectors.

like image 79
ceejayoz Avatar answered Sep 18 '22 23:09

ceejayoz