【问题标题】:CSS Variables (custom properties) in Pseudo-element "content" Property伪元素“内容”属性中的 CSS 变量(自定义属性)
【发布时间】:2017-03-03 00:41:10
【问题描述】:

示例使用(我想要的)

div::after {
  content: var(--mouse-x) ' / ' var(--mouse-y);
}

测试用例显示它不起作用:

CodePen: CSS Variables in Pseudo Element's "content:" Property (a test case) by Jase Smith

document.addEventListener('mousemove', (e) => {
  document.documentElement.style.setProperty('--mouse-x', e.clientX)
  document.documentElement.style.setProperty('--mouse-y', e.clientY)
  
  // output for explanation text
  document.querySelector('.x').innerHTML = e.clientX
  document.querySelector('.y').innerHTML = e.clientY
})
/* what I want!! */
div::after {
  content: var(--mouse-x, 245)" / " var(--mouse-y, 327);
}

/* setup and presentation styles */
div::before {
  content: 'mouse position:';
}
div {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(calc(var(--mouse-x, 245) * 1px), calc(var(--mouse-y, 327) * 1px));
  width: 10em;
  height: 10em;
  background: #ff3b80;
  color: #fff;
  display: flex;
  flex-flow: column;
  align-items: center;
  justify-content: center;
  border-radius: 100%;
  will-change: transform;
}
body {
  margin: 2em;
  font-family: sans-serif;
}
p {
  max-width: 50%;
  min-width: 25em;
}
<!-- test case: element with pseudo element -->
<div></div>

<!-- explanation (not test case) -->
<main>
  <pre><code>div::after {
  content: var(--mouse-x) ' / ' var(--mouse-y);
}</code></pre>
  <h1>If this worked...</h1>
  <p>
    We should see something like this: <b><span class="x">245</span> / <span class="y">327</span></b> updating with the mousemove coordinates inside the pseudo <i>::after</i> element for the div.
  </p>
</main>

【问题讨论】:

  • 我建议直接在问题中发布代码,以防将来链接中断。
  • 啊,谢谢你的提示。我希望它只是嵌入并显示 CodePen 演示......
  • 这是 stackoverflow.com/questions/38751778/… 的副本,但由于您在这里处理数字,所以 darrylyeo 的 hack 就可以了。

标签: css pseudo-element css-variables


【解决方案1】:

编辑清楚:具有整数值的 CSS 自定义属性可以通过 CSS counter 显示在伪元素的 content 属性中。

div {
    --variable: 123;
}
span:after {
    counter-reset: variable var(--variable);
    content: counter(variable);
}
&lt;div&gt;The variable is &lt;span&gt;&lt;/span&gt;.&lt;/div&gt;

.coordinates:before {
    counter-reset: x var(--x) y var(--y);
    content: 'The coordinates are (' counter(x) ', ' counter(y) ').';
}
&lt;div class="coordinates" style="--x: 1; --y: 2"&gt;&lt;/div&gt;

原答案

使用涉及 CSS Counters 的 hack 让它工作。享受吧。

div::after {
  counter-reset: mouse-x var(--mouse-x, 245) mouse-y var(--mouse-y, 245);
  content: counter(mouse-x) " / " counter(mouse-y);
}

完整代码:

document.addEventListener('mousemove', (e) => {
  document.documentElement.style.setProperty('--mouse-x', e.clientX)
  document.documentElement.style.setProperty('--mouse-y', e.clientY)
  
  // output for explanation text
  document.querySelector('.x').innerHTML = e.clientX
  document.querySelector('.y').innerHTML = e.clientY
})
/* what I want!! */
div::after {
  counter-reset: mouse-x var(--mouse-x, 245) mouse-y var(--mouse-y, 245);
  content: counter(mouse-x) " / " counter(mouse-y);
}

/* setup and presentation styles */
div::before {
  content: 'mouse position:';
}
div {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(calc(var(--mouse-x, 245) * 1px), calc(var(--mouse-y, 327) * 1px));
  width: 10em;
  height: 10em;
  background: #ff3b80;
  color: #fff;
  display: flex;
  flex-flow: column;
  align-items: center;
  justify-content: center;
  border-radius: 100%;
  will-change: transform;
}
body {
  margin: 2em;
  font-family: sans-serif;
}
p {
  max-width: 50%;
  min-width: 25em;
}
<!-- test case: element with pseudo element -->
<div></div>

<!-- explanation (not test case) -->
<main>
  <pre><code>div::after {
  content: var(--mouse-x) ' / ' var(--mouse-y);
}</code></pre>
  <h1>If this worked...</h1>
  <p>
    We should see something like this: <b><span class="x">245</span> / <span class="y">327</span></b> updating with the mousemove coordinates inside the pseudo <i>::after</i> element for the div.
  </p>
</main>

【讨论】:

  • 聪明的解决方案,只需从您的counter-reset 属性中删除245 值,它们不是必需的。
  • 啊!这很棒 :) 一组变量,没有直接的 DOM 操作。爱它。非常感谢!
  • 很高兴接受挑战!
  • 为非整数值打印0(例如1.1
【解决方案2】:

content 属性仅允许 Strings,并且由于您与数字不对齐并且 CSS 无法转换变量,因此您可以选择创建另一组变量(来自 JS),这些变量将提供作为打印值,类型为String

要将--mouse-x-text 设置为String,使用旧的转换技巧2+"" = "2" 将其转换为该类型是不够的,但JSON.stringify 是我所知道的唯一可以输出“真实”字符串的方法, 从已经是字符串的值中,这意味着字符串中的字符串,因为 CSS 似乎剥离了第一个字符串层。

document.addEventListener('mousemove', ({clientX:x, clientY:y}) => {
  const {style} = document.documentElement

  style.setProperty('--mouse-x', x)
  style.setProperty('--mouse-y', y)

  // for printing
  style.setProperty('--mouse-x-text', JSON.stringify(x+""))
  style.setProperty('--mouse-y-text', JSON.stringify(y+""))
})
body::before{
  content: "X:"var(--mouse-x-text)"  Y:"var(--mouse-y-text);
}

【讨论】:

    【解决方案3】:

    我不太确定我是否正确理解了您的问题,但我认为这是一个解决方案...

    您可以为 &lt;div&gt; 元素定义自定义属性。

    <div data-position></div>
    

    然后用javascript在这个属性中赋值:

      var position = e.clientX + " " + e.clientY
      document.querySelector("div").setAttribute('data-position', position)
    

    最后在你的伪元素的content 属性中使用attr() CSS 函数。

    div::after {
      content: attr(data-position);
    }
    

    然后瞧。


    代码片段:

    document.addEventListener('mousemove', (e) => {
      document.documentElement.style.setProperty('--mouse-x', e.clientX)
      document.documentElement.style.setProperty('--mouse-y', e.clientY)
      var position = e.clientX + "/" + e.clientY
      document.querySelector("div").setAttribute('data-position', position)
        // output for explanation text
      document.querySelector('.x').innerHTML = e.clientX
      document.querySelector('.y').innerHTML = e.clientY
    })
    /* what I want!! */
    
    div::after {
      content: attr(data-position);
    }
    /* setup and presentation styles */
    
    div::before {
      content: 'mouse position:';
    }
    div {
      position: absolute;
      top: 0;
      left: 0;
      transform: translate(calc(var(--mouse-x, 245) * 1px), calc(var(--mouse-y, 327) * 1px));
      width: 10em;
      height: 10em;
      background: #ff3b80;
      color: #fff;
      display: flex;
      flex-flow: column;
      align-items: center;
      justify-content: center;
      border-radius: 100%;
      will-change: transform;
    }
    body {
      margin: 2em;
      font-family: sans-serif;
    }
    p {
      max-width: 50%;
      min-width: 25em;
    }
    <div data-position></div>
    <span class="x"></span>/<span class="y"></span>

    【讨论】:

    • 谢谢@Ricky_Ruiz。抱歉,我的帖子没有更清楚。虽然您的解决方案产生了功能性结果,但我更感兴趣的是使用 CSS 自定义属性功能,而不是直接对元素(及其属性)进行 DOM 操作。
    • @Jase 明天早上我会再试一次,看看我能否提供适合您所寻找的答案。希望这可以按照您想要的方式解决。会及时更新。干杯。
    • @Jase 检查 DarryLeo 的answer
    【解决方案4】:

    您需要为自定义属性的值加上引号。

    document.documentElement.style.setProperty('--mouse-x', "'" + e.clientX + "'")
    document.documentElement.style.setProperty('--mouse-y', "'" + e.clientY + "'")
    

    【讨论】:

    • 但这似乎打破了它用作 int 的定位,我猜 CSS 不会像 JS 那样为你做类型转换。
    • 这非常接近我想要的。然而,虽然这提供了纯粹基于 CSS 变量的伪元素中的值的实时更新,但正如@DBS 所指出的那样,DIV 失去了它的定位功能,这真是令人遗憾。
    • @Jase 显然这并不理想,但您可以只存储相同值的 int 和字符串版本(例如,“--mouse-x”用于 int,“--mouse-xs”用于string) 并在需要时使用相关的数据类型。
    • 同意,目前还没有办法用一组变量来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2013-12-06
    • 2018-12-04
    • 2019-04-12
    • 1970-01-01
    • 2018-07-15
    相关资源
    最近更新 更多