javascript - Dynamic styling for pseudo element's content in Vue2.x - Stack Overflow

I have a ponent that is basically an Icon and a tooltip; it shows the tooltip( whose text es from the p

I have a ponent that is basically an Icon and a tooltip; it shows the tooltip( whose text es from the parent ponent as a prop) on mouse hover. I implemented the tooltip with the help of pseudo-elements so I need to update the pseudo element's content with the prop's value. I am also aware of the fact that Pseudo element rules of CSS aren’t part of the DOM, and therefore they can’t be altered using JavaScript methods, but I found a bunch of workarounds that basically work for any CSS property but not content(I can see they work (e.g. for width property of tooltip or its color ) but strangely not for the content property), here is what I have done so far, any help would be appreciated:

<template>
    <div>
        <!-- <style>
            :root {
            --info-msg: {{tooltipContent}};
            }
        </style> -->
        <div class="infoBar">
            <svg-icon
                fill="#d5d5dc"
                :width="16"
                :height="16"
                name="mon/c-info"
                class="infoBar__icon"
            />
        </div>
    </div>

</template>

<script>
export default {
  name: 'ContentInfo',
  props: {
    tooltipContent: {
      type: String,
      default: 'hint text goes here'
    }
  },
  mounted () {
    console.log(this.tooltipContent)
    this.applyCSS()
  },

  beforeUpdate () {
    this.applyCSS()
  },
  methods: {
    applyCSS () {
      const cssRule = `
      .infoBar:after{
        content: ${this.tooltipContent};
      }`
      const style = document.createElement('style')
      style.type = 'text/css'
      this.$el.appendChild(style)
      style.innerHTML = cssRule
    }
  }

}
</script>

<style lang="postcss" >

  .infoBar{
    position: relative;
    margin-left: 24px;
    &::after {
      background-color: #000;
      font-size: 12px;
      color: #fff;
      border-radius: 2px;
      width: 198px;
      height: 40px;
     /*content: var(--info-msg)*/
      display: none;
      padding: 11px 26px 10px 27px;
      position: absolute;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px));
      z-index: 999;
    }
    &::before {
      background-color: #000;
      content: '';
      display: none;
      position: absolute;
      width: 10px;
      height: 6px;
      z-index: 999;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px)) rotate(45deg);
    }
    &:hover::after {
      display: block;
    }
    &:hover::before {
      display: block;
    }
    &__icon:hover{
        fill: #e4002b;
      }
  }

  </style>

I have a ponent that is basically an Icon and a tooltip; it shows the tooltip( whose text es from the parent ponent as a prop) on mouse hover. I implemented the tooltip with the help of pseudo-elements so I need to update the pseudo element's content with the prop's value. I am also aware of the fact that Pseudo element rules of CSS aren’t part of the DOM, and therefore they can’t be altered using JavaScript methods, but I found a bunch of workarounds that basically work for any CSS property but not content(I can see they work (e.g. for width property of tooltip or its color ) but strangely not for the content property), here is what I have done so far, any help would be appreciated:

<template>
    <div>
        <!-- <style>
            :root {
            --info-msg: {{tooltipContent}};
            }
        </style> -->
        <div class="infoBar">
            <svg-icon
                fill="#d5d5dc"
                :width="16"
                :height="16"
                name="mon/c-info"
                class="infoBar__icon"
            />
        </div>
    </div>

</template>

<script>
export default {
  name: 'ContentInfo',
  props: {
    tooltipContent: {
      type: String,
      default: 'hint text goes here'
    }
  },
  mounted () {
    console.log(this.tooltipContent)
    this.applyCSS()
  },

  beforeUpdate () {
    this.applyCSS()
  },
  methods: {
    applyCSS () {
      const cssRule = `
      .infoBar:after{
        content: ${this.tooltipContent};
      }`
      const style = document.createElement('style')
      style.type = 'text/css'
      this.$el.appendChild(style)
      style.innerHTML = cssRule
    }
  }

}
</script>

<style lang="postcss" >

  .infoBar{
    position: relative;
    margin-left: 24px;
    &::after {
      background-color: #000;
      font-size: 12px;
      color: #fff;
      border-radius: 2px;
      width: 198px;
      height: 40px;
     /*content: var(--info-msg)*/
      display: none;
      padding: 11px 26px 10px 27px;
      position: absolute;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px));
      z-index: 999;
    }
    &::before {
      background-color: #000;
      content: '';
      display: none;
      position: absolute;
      width: 10px;
      height: 6px;
      z-index: 999;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px)) rotate(45deg);
    }
    &:hover::after {
      display: block;
    }
    &:hover::before {
      display: block;
    }
    &__icon:hover{
        fill: #e4002b;
      }
  }

  </style>
Share edited Feb 28, 2021 at 17:21 BlackSheep asked Feb 28, 2021 at 12:55 BlackSheepBlackSheep 6132 gold badges10 silver badges19 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

follow these steps and you can use props in the css as css variables:

  1. use props in a puted to return an object of css variables and bind this object to the style of the ponent
  2. you should give the ponent a class name as the css variables can be accessed from within the class name in the css style section
  3. as for css variables that should be in the string format to work correctly you should use JSON.stringify() (this is the case for the content css property)

run the example bellow and see for yourself, both color and text of the after element showing by hover are ing as a prop from the parent ponent:

Vue.ponent('pseudo', {
  data() {
    return {
      title: 'Hover me',
    }
  },
  props: {
    color: {
      type: String,
    },
    text: {
      type: String,
    }
  },
  puted: {
    cssVars() {
      return {
        '--color': this.color,
        '--text': JSON.stringify(this.text),
      }
    }
  },
  template: `<div class="content" :style="cssVars">{{title}}</div>`,
});

var vm = new Vue({
  el: '#app',
});
.content {
  color: red;
}

.content:hover::after {
  content: var(--text);
  color: var(--color);
  margin-left: 20px;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <pseudo color="green" text="I'm from Prop!!"></pseudo>
</div>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745044892a4608035.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信