CSS alpha() relative color function

Status: Intent to Ship in Gecko

Syntax

--brand: oklch(58% 0.2 265);
background: alpha(from var(--brand) / 35%);

Demo

Same color, different opacity

var(--brand)
alpha()
background: alpha(from var(--brand) / 35%);

CSS progress() function

Status: Intent to Ship in Gecko

Syntax

opacity: progress(5, 0, 10);

/* Use calc() only when converting the ratio into a unit */
width: calc(progress(700px, 320px, 1200px) * 100%);

Demo

Map a value to a 0-1 ratio

opacity: progress(520, 0, 1000)
052%1000
opacity: progress(520, 0, 1000);

/* if you need a percentage width */
width: calc(progress(520, 0, 1000) * 100%);

Promise.allKeyed()

Status: Intent to Ship in Gecko; TC39 proposal

Syntax

const { user, posts } = await Promise.allKeyed({
  user: fetchUser(),
  posts: fetchPosts(),
});

Demo

Promise results keep their keys

userWes #1
posts13
settingslight
const data = await Promise.allKeyed({
  user: fetchUser(),
  posts: fetchPosts(),
  settings: fetchSettings(),
});

// {
  "user": "Wes #1",
  "posts": 13,
  "settings": "light"
}

<camera> and <microphone> elements

Status: Intent to Prototype in Chromium

Syntax

<camera></camera>
<microphone></microphone>

Demo

Example code

<camera id="camera"></camera>
<video id="preview" autoplay playsinline></video>

<script>
  camera.addEventListener("track", () => {
    preview.srcObject = new MediaStream([camera.track]);
  });
</script>

Advanced CSS attr() function

Status: Intent to Ship in Gecko

Syntax

.card {
  background: attr(data-color type(<color>), hotpink);
  width: attr(data-width px, 240px);
}

Demo

Attributes become typed CSS values

data-color="#315ee4"
data-width="280"
<div class="card" data-color="seagreen" data-width="280"></div>

.card {
  background: attr(data-color type(<color>), hotpink);
  width: attr(data-width px, 240px);
}

CSS sibling-index() and sibling-count()

Status: Intent to Ship in Gecko for Firefox 154

Syntax

.item {
  width: calc(sibling-index() * 40px);
  background: hsl(
    calc(360deg / sibling-count() * sibling-index()) 70% 55%
  );
}

Demo

Calculate from position and total count

6 items
1
2
3
4
5
6
.dot {
  --angle: calc(360deg / sibling-count() * sibling-index());
  rotate: var(--angle);
  translate: 0 -90px;

  background: hsl(
    calc(360deg / sibling-count() * sibling-index()) 70% 55%
  );
}

CSS shrink-to-fit container

Status: Intent to Prototype in Chromium

Syntax

.outer {
  max-content-sizing: shrink-to-fit;
  text-wrap: balance;
  width: fit-content;
  max-width: 320px;
}

.inner {
  width: fit-content;
}

Demo

Shrink the box to the widest wrapped line

current fit-content
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Box stays at the 320px constraint after wrapping.
max-content-sizing: shrink-to-fit
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Target behavior: box width becomes the widest actual line.
<div class="outer">
  <div class="inner">
    Lorem ipsum dolor sit amet...
  </div>
</div>

.outer {
  max-content-sizing: shrink-to-fit;
  text-wrap: balance;
  width: fit-content;
  max-width: 320px;
}

.inner {
  width: fit-content;
}

CSS text-box-trim and text-box-edge

Status: Intent to Prototype in Gecko

Syntax

.button {
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

.heading {
  text-box: trim-both cap alphabetic;
}

Demo

Trim extra font space above and below text

normal
Agypqj
text-box: normal;
trim-start
Agypqj
text-box-trim: trim-start;
trim-end
Agypqj
text-box-trim: trim-end;
trim-both + cap alphabetic
Agypqj
text-box: trim-both cap alphabetic;
trim-both + ex text
Agypqj
text-box: trim-both ex text;
.label {
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

/* shorthand */
.label {
  text-box: trim-both cap alphabetic;
}