There's no audio in CSS. Why not?

Seems like the ability for a checkbox (for example) to trigger a sound when it is checked or unchecked is an inherent part of styling (audible instead of visible).

Maybe CSS can have such abilities. F.e.


input[type=checkbox] {
  audio: './path/to/pop1.mp3';
}
input[type=checkbox]:checked {
  audio: './path/to/po2.mp3';
}

and the audio only plays on state changes, not on initial styling. That way if there are 100 check boxes, 100 pop sounds don’t start playing when the page loads. So it’s like CSS animations, which start animating on a state change, and initial values are static.

3 Likes

Opening question is intriguing. :grinning:

Looking in, it looks more or less like event-based sounds - which is already possible in JavaScript. But then… the sweet spot of CSS - declarativeness - which no one says no to.

Now, it could even be better if we could create tones declaratively, just as we do create colours using RGB, HSL, etc. This can let us follow a “keyframes” approach for CSS sounds instead of downloading a file:

@keysounds sound1 {
  0%   {background: bit(0.3245);, foreground: bit(1);}
  100%   {background: bit(0.3245);, foreground: bit(0.943);}
}

div:hover {
  audio-name: sound1;
  audio-duration: 4s;
}

Please pardon whatever looks too funny, as I know nothing about properties of a sound. But being able to define sounds right in CSS @keysounds would give the browser perfect control and can minimize web sounds abuse - like inappropriately linking to long-playing music.

How does this itself sound?

3 Likes

Interesting!

I think though, we’d probably want to keep @keyframes instead of @keysounds, and then have new properties specific for the audio, for example this can allow any properties (visual or audible) to be animated the same way. For example, the following animates both audio and visuals:

@keyframes my-animation {
  0%   {
    audio-background: bit(0.3245);
    audio-foreground: bit(1);
    background-color: cornflowerblue;
  }
  100%   {
    audio-background: bit(0.3245);
    audio-foreground: bit(0.943);
    background-color: salmon;
  }
}

div:hover {
  animation: my-animation 4s;
}

If we wanted to, we could create separate @keyframes for the audio and visuals.

This is interesting though. However I’m also not 100% sure what it means to have a tree of DOM elements with audio properties on them.

For example, what does it mean if we write

div {
    audio-background: bit(0.3245);
    audio-foreground: bit(0.943);
}

and we have, say, 100 divs in the page, some of them nested in each other? EDIT: Maybe audio is exclusive to animations? EDIT: Maybe the tree of DOM nodes can represent a tree of audio nodes, where the root node is always the output node?

I wonder what are all the primitives we’d need for audio.

2 Likes
There's a decent audio tag, so if you get that involved with the checkbox you're looking at interaction between multiple elements.

So maybe something like this:

myCheckbox:not(:checked):click {
    #myAudioTag {
        media-control: play;
    }
}

myCheckbox:checked:click {
    #myAudioTag {
        media-control: stop;
    }
}

or

myDiv:mouseover {
    #myAudioTag {
        media-control: play;
    }
}

myDiv:mouseout {
    #myAudioTag {
        media-control: stop;
    }
}

Example of it in action:

https://activecss.org/manual/simple-html5-audio-controls.html

Event-driven architecture is the whole point behind Active CSS, which is a playground for turning CSS into a proper event-driven language. [edit - oops, you already knew that trusktr, sorry - I just spotted who wrote the original post - I’ll leave that there for people who don’t know what it is] The main upgrade needed to CSS to keep things simple is to add cause and effect selectors going on for interactions concerning multiple elements.

The comments about bits - do you mean like make a short noise defined by CSS? Like audio creation in CSS? That would be really cool. I think I only just got the point of those comments - I saw the word “bit” and I think I bounced out without getting the point. But what I wrote here does answer the first question. How about also having a set of pre-defined noises in the browser and a way to set them off with CSS? That might be a bit 90s though…

With regards triggering the animation off dynamically on checkbox click rather than an audio file, you could do what’s below (or alternatively just use the animation CSS command itself where add-class is):

myCheckbox:not(:checked):click {
    body {
        add-class: .classThatDeclaresTheAnimation;
    }
}

myCheckbox:click {
    body {
        remove-class: .classThatDeclaresTheAnimation;
    }
}

or

myCheckbox:not(:checked):click {
    animation: my-animation 4s;
}

With regards this:

div:hover {
    audio-name: sound1;
    audio-duration: 4s;
}

or even this:

div:hover {
    audio: sound1 4s;
}

It’s almost there, but the thing is - hover is only one event, which is pretty limiting. As alluded in the Active CSS concept, having access to all the available events would be beneficial. It has nothing particularly to do with compatibility with the rendering engine stopping something like this from being implemented. The event-driven commands could simply be set up to run via JavaScript like with Active CSS, except at lower-level, and the performance would be absolutely fine. In fact, it may even be easier to implement something like this using the existing lower-level APIs if event-driven actions like this were channelled in that direction, as it isn’t really anything to do with rendering.

Something like the audio generation could be prototyped in Active CSS via the Web Audio API relatively easily (ie. using the @command syntax to create the “audio” command or something like it). Someone could take a look at it. It may be a while before I get to it as I’ve got a decent size roadmap for Active CSS as it is - mainly around the area of components.

The magic in this though would be in harnessing all the existing Web Audio API lower-level sound generation options into a single CSS command for playing a noise. In theory this should be possible as it is only one action, but I don’t know enough about how it works to be certain of that.

The MDN audio example looks to be a good place to start investigating:

In addition to being able to play a generated noise via a CSS command, it would be handy to tie in the visualization options. I’ve used these before to build graphic equalizer CSS animations, so tying this directly into CSS would be cool too. Imagine a CSS command to synchronize CSS with audio without having to get into writing JavaScript - that would be amazing! I have no idea what the CSS command for that would look like though.