【问题标题】:How to set pseudo elements properties dynamically?如何动态设置伪元素属性?
【发布时间】:2021-11-08 20:58:37
【问题描述】:

我正在尝试在 HTML5 视频上叠加水印,并根据用户选择设置视频上水印的位置。

CSS

/*Video.module.css*/

.wrapper {
    position: relative;
    height: 100%;
}

.wrapper::before {
    display: block;
    position: absolute;
    top: 2%;
    left: 2%;
    height: 18%;
    width: 18%;
    content: '';
    background: 'red';
}

JSX

import styles from 'styles/Video.module.css';

const Video = ({ src }) => {
    return (
        <div class={styles.wrapper}>
            <video src={src}>
                <track type='captions' />
            </video>
        </div>
    );
};

使用当前样式,水印位于视频的左上角。我想让用户选择位置。

目前,我的方法是为每个位置创建一个 css 类选择器,如下所示,并使用 useState 挂钩根据用户选择设置类。

CSS

.wrapper-top-right {
    position: relative;
    height: 100%;
}

.wrapper-top-right::before {
    top: 2%
    right: 2%
    ....
}

.wrapper-bottom-right {
    ....
}

.wrapper-bottom-right::before {
    bottom: 2%;
    right: 2%;
    ....
}

JSX

import styles from 'styles/Video.module.css';
import React, {useState} from 'react';

const Video = ({ src }) => {
    //Values: 'top-left', 'bottom-left', 'top-right', 'bottom-right'
    const [position, setPosition] = useState('top-left'); 

    return (
        <div class={`styles[${position}]`}>
            <video src={src}>
                <track type='captions' />
            </video>
            /** Button with code to set position.... **/
        </div>
    );
};

但这绝对不是理想的,因为 CSS 文件中有重复的代码。想知道是否有办法动态设置属性(在本例中为top, bottom, left, right),这样我只需要一个类选择器。

【问题讨论】:

  • 你不能动态设置伪元素的样式,但也许 CSS 变量可以成为一个解决方案。

标签: javascript css reactjs pseudo-element


【解决方案1】:

在父元素上设置--custom-property。我将在此处使用 :hover 更改值,但您应该也可以看到如何在 style 属性中完成它:

div {

  /* Important bits */
  --watermarkBottom: 0;
  --watermarkTop: initial;

  /* Boilerplate */
  width: 100px;
  height: 100px;
  background-color:red;
  position: relative;
}

div:hover {
  /* Important bits */
  --watermarkBottom: initial;
  --watermarkTop: 0;
}

div::after {
  /* Important bits */
  bottom: var(--watermarkBottom);
  top: var(--watermarkTop);

  /* Boilerplate */
  content: 'watermark';
  background-color:blue;
  color:white;
  position: absolute;
}
&lt;div&gt;&lt;/div&gt;

【讨论】:

    【解决方案2】:

    您可以使用为宿主元素设置的 CSS 自定义属性。

    我不会说 React,所以快速香草 POC:

    .wrapper::before {
      position: absolute;
      top: var(--before-top, 0%);
      left: var(--before-left, 0%);
      background: red;
      color: white;
      content: var(--before-content, '?');
    }
    .wrapper {
      position: relative;
      height: 100px;
      outline: #0FF6 solid;
      outline-offset: -2px;
    }
    label { display: block; }
    <label>Top: <input type="range" value="0" min="0" max="100" 
     oninput="w.style.setProperty('--before-top', this.value + '%')"></label>
    <label>Left: <input type="range" value="0" min="0" max="100" 
     oninput="w.style.setProperty('--before-left', this.value + '%')"></label>
    <label>Content: <input type="text" value="?" 
     oninput="w.style.setProperty('--before-content', `'${this.value}'`)"></label>
    <div class="wrapper" id="w"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-01
      • 2015-05-06
      • 2018-07-17
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      相关资源
      最近更新 更多