[英]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.我正在尝试使用 Vue.js 创建一个旋转文本
Vue.js
,我用这个CodePen作为灵感。
I got all the HMTL
elements properly in place (ie, as in the CodePen mentioned).我把所有的
HMTL
元素都放在了适当的位置(即,正如在CodePen中提到的那样)。 In short:简而言之:
<span>
elements, each containing one letter.<span>
元素组成,每个元素包含一个字母。<span>
that holds a letter gets applied an .in
and .out
CSS
class.<span>
都会应用一个.in
和.out
CSS
class。 This goes on indefinitely. here is what it looks like in the DOM
:这是它在
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
:问题是,无论我使用什么
CSS
选择器,我都无法定位.in
和.out
类,除非我通过Chrome
中的Developer Tools
进行操作:
Here is the bare minimum code of my Vue Component
:这是我的
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?是什么问题阻止了这些类的应用?
You're using v-html
, but that doesn't work with scoped styles .您正在使用
v-html
,但这不适用于范围样式。
DOM content created with
v-html
are not affected by scoped styles, but you can still style them using deep selectors.使用
v-html
创建的 DOM 内容不受范围样式的影响,但您仍然可以使用深度选择器来设置它们的样式。
Yes,是的,
v-html
v-html
doesn't work with scoped styles.不适用于范围样式。
As Brock Reece explained in his article Scoped Styles with v-html , it should be solved like this:正如 Brock Reece 在他的文章Scoped Styles with v-html 中解释的那样,应该这样解决:
<template>
<div class="a" v-html="content"></div>
</template>
<script>
export default {
data() {
return {
content: 'this is a <a class="b">Test</a>',
}
},
}
</script>
<style scoped>
.a >>> .b {
color: red;
}
</style>
This worked for me:这对我有用:
<template>
<div class="a" v-html="content"></div>
</template>
<script>
export default {
data() {
return {
content: 'this is a <a class="b">Test</a>',
}
},
}
</script>
<style scoped>
.a ::v-deep .b {
color: red;
}
</style>
Most answers are deprecated now that Vue3 is out.由于 Vue3 已经发布,大多数答案都已被弃用。 Up-to-date usage of deep selector:
深度选择器的最新用法:
.letter{
&:deep(.in) {
color:blue;
}
&:deep(.out) {
color:red;
}
}
Vue3: In Single-File Components, scoped styles will not apply to content inside v-html, because that HTML is not processed by Vue's template compiler. Vue3:在单文件组件中,作用域 styles 将不适用于 v-html 内的内容,因为 Vue 的模板编译器不会处理 HTML。
You can use:deep() inner-selector in Vue3 project.您可以在 Vue3 项目中使用:deep() 内部选择器。
Here is a example:这是一个例子:
<script setup lang="ts">
import {onMounted,ref } from 'vue'
const content = ref("")
onMounted(()=>{
window.addEventListener('keydown',event =>{
content.value = `
<div class="key">
<span class="content">${event.keyCode}</span>
<small>event.keyCode</small>
</div>
`
})
})
</script>
<template>
<div class="container" v-html="content">
</div>
</template>
<style lang="scss" scoped>
.container{
display: flex;
:deep(.key){
font-weight: bold;
.content{
font-size: 1.5rem;
}
small{
font-size: 14px;
}
}
}
</style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.