You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CSS实现交互性听觉表现?相关技术问询

前端技术分工共识
  • HTML负责structure(结构)
  • CSS负责presentation(表现)
  • JS负责behaviour(行为)

注: 我们可探讨“响应用户交互的表现”是否等同于“行为”,这是一种观点。但网页上大量通过:hover、:focus、:focus-within等伪类实现的纯CSS交互视觉效果,说明另一种观点被广泛接受:CSS是处理“交互性表现”的合法技术。

技术问询

既然CSS可实现多种交互视觉表现,是否可用于处理交互性听觉表现?

  1. 是否曾有尝试在CSS中引入aural presentation(听觉表现)?
  2. 是否有在CSS中引入听觉表现的提案?

是否存在官方方案(即使未被浏览器实现),可通过以下虚构CSS属性实现如下Demo的效果:

  • audio
  • audio-duration
  • audio-play

示例Demo

请忽略下方JavaScript代码,假设如下CSS样式可直接生效:

.square:unhover {
  audio: url(//cdn.freesound.org/previews/628/628357_1486333-lq.mp3);
  audio-duration: 1.776s;
  audio-play: 2;
}

实现逻辑(JavaScript)

// BUILD STYLESHEET ARRAY
const stylesheet = document.head.querySelector('style');
let stylesheetText = stylesheet.textContent.replace(/\s/g, '');
let stylesheetArray = stylesheetText.split('}');
stylesheetArray.pop();

// BUILD SELECTORS ARRAY
let selectorsArray = [];
for (let i = 0; i < stylesheetArray.length; i++) {
  selectorsArray[i] = {
    selector: stylesheetArray[i].split('{')[0],
    styles: {}
  };
  
  let selectorRules = stylesheetArray[i].split('{')[1].split(';')
  selectorRules.pop();
  
  for (let j = 0; j < selectorRules.length; j++) {
  
    selectorsArray[i].styles[selectorRules[j].split(':')[0]] = selectorRules[j].split(':')[1];
  }
}

// BUILD TARGET QUERIES ARRAY
let targetQueriesArray = [];

for (let i = 0; i < selectorsArray.length; i++) {
  
  if ((/:hover|:unhover/).test(selectorsArray[i].selector)) {
  
    if (Object.keys(selectorsArray[i].styles).includes('audio')) {
  
      let targetQuery = selectorsArray[i];
      
      switch (true) {
    
        case (targetQuery.selector.includes(':hover')): targetQuery.event = 'mouseover'; break;
        case (targetQuery.selector.includes(':unhover')): targetQuery.event = 'mouseout'; break;
      }
    
      targetQueriesArray.push(targetQuery);
    }
  }
}

// DECLARE playAudioViaCSS FUNCTION
const playAudioViaCSS = (audioURL, audioDuration, audioPlays) => {

  let soundEffectViaCSS = new Audio(audioURL);
  soundEffectViaCSS.loop = true;
  soundEffectViaCSS.play();
  
  setTimeout(() => soundEffectViaCSS.loop = false, (audioDuration * audioPlays));
}

// ATTACH AUDIO EVENTS TO TARGET ELEMENTS
for (let i = 0; i < targetQueriesArray.length; i++) {
 
  let targetAudio = targetQueriesArray[i].styles.audio.replace('url(', '').replace(')', '');
  let targetAudioDuration = (targetQueriesArray[i].styles['audio-duration'].replace('s', '') * 1000) || 1000;
  let targetAudioPlays = targetQueriesArray[i].styles['audio-play'] || 1;
  let targetEvent = targetQueriesArray[i].event;
  let targetQuery = targetQueriesArray[i].selector.replace(/:hover|:unhover/g, '');

  let targetElements = [...document.querySelectorAll(targetQuery)];
  targetElements.forEach((element) => element.addEventListener(targetEvent, () => playAudioViaCSS(targetAudio, targetAudioDuration, targetAudioPlays), false));
};

样式定义(CSS)

:root {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.square {
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
  color: rgb(255, 255, 255);
  background-color: rgb(255, 0, 0);
  border-radius: 50%;
  cursor: pointer;
  transform: scale(1);
  transition: all 0.9s ease-out; 
}

.square:hover {
  border-radius: 0;
  transform: scale(1.5);
  audio: url(//cdn.freesound.org/previews/354/354062_1490240-lq.mp3);
  audio-duration: 2.304s;
  audio-play: 3;
}

.square:unhover {
  audio: url(//cdn.freesound.org/previews/628/628357_1486333-lq.mp3);
  audio-duration: 1.776s;
  audio-play: 2;
}

页面结构(HTML)

<div class="square">
Hover me
</div>

内容的提问来源于stack exchange,提问作者Rounin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:54:28