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:
<span>
elements, each containing one letter.<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
:
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:
output after I added the classes in Developer Tools
:
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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With