Exit
1 / 60

Newly Acquired Powers of the Web Platform

Speaker notes

Since 2020 speed up.

Firefox and Chrome – two week cadence.

Three main languages.

2 / 60

This is a rather long heading that will break into two separate lines

3 / 60

This is a rather long heading that will break into two separate lines

Speaker notes

Seen in hero.

4 / 60

This is a rather long heading that will break into two separate lines

Speaker notes

Manual line break addition.

5 / 60

This is a rather long heading that will break into two separate lines

h1 {
				text-wrap: balance;
			}
			
6 / 60
.icons {
				display: flex;
				flex-wrap: wrap;
			}
			
7 / 60
.icons {
				display: flex;
				flex-wrap: balance;
			}
			
8 / 60

Corner Shape

9 / 60
10 / 60
border-radius: 0;
border-radius: 30px;
border-radius: 50%;

Speaker notes

What if you want different rounding?

11 / 60
border-radius: 0; corner-shape: squircle;
border-radius: 30px; corner-shape: squircle;
border-radius: 50%; corner-shape: squircle;

Speaker notes

Superellipse – maths! Tapered curve

Apple and Samsung uses in interfaces.

Keeps the radius.

12 / 60
corner-top-right-shape: square;
corner-top-right-shape: bevel;
corner-top-right-shape: scoop;
corner-top-right-shape: notch;
corner-top-right-shape: superellipse(3);

Speaker notes

Same border-radius, different corner-shape.

Had to use clip-path hacks. Image masks.

13 / 60
14 / 60

Text Box

text-box text-box-edge

Speaker notes

Whitespace. Lineheight hacks

15 / 60

This is text without any text-box value.

This is text with text-box: trim-start cap alphabetic;.

This is text with text-box: trim-end cap alphabetic;.

This is text with text-box: trim-both cap alphabetic;.

16 / 60

This is text without any text-box value.

This is text with text-box: trim-start cap alphabetic;.

This is text with text-box: trim-end cap alphabetic;.

This is text with text-box: trim-both cap alphabetic;.

Speaker notes

Margin/padding control. Alignment.

17 / 60

Sibling Functions

sibling-index() sibling-count()

Speaker notes

sibling-index() returns position of an item relative to adjacent items.

sibling-count() returns number of sibling elements an element possesses, including itself.

Mention nth-child

18 / 60
  1. Item One
  2. Item Two
  3. Item Three
  4. Item Four
li {
				margin-inline-start: calc(sibling-index() * 20px);
			}
			

Speaker notes

1st item gets 20px, 2nd gets 40px, 3rd gets 60px, etc

19 / 60
  1. Item One
  2. Item Two
  3. Item Three
  4. Item Four
li {
				opacity: calc(sibling-index() / sibling-count());
			}
			

Speaker notes

sibling-index() returns position of an item relative to adjacent items.

sibling-count() returns number of sibling elements an element possesses, including itself.

20 / 60
  1. Item One
  2. Item Two
  3. Item Three
  4. Item Four
  5. Item Five
  6. Item Six
li {
				opacity: calc(sibling-index() / sibling-count());
			}
			
21 / 60

Colour Mix

color-mix()

Speaker notes

Functions invoke special data processing or calculations.

22 / 60
background: blue;
background: yellow;
background: green;
23 / 60
background: color-mix(blue 30%, yellow);
			
24 / 60
background: color-mix(blue 80%, yellow);
			
25 / 60
background: color-mix(red, green);
			
26 / 60
background: green;
			
background: color-mix(green, transparent);
			

Speaker notes

opacity effects element’s opacity.

Why not precompute/process?

Different colour formats.

27 / 60
28 / 60

Contrast Colour

contrast-color()

29 / 60

This is text.

30 / 60

This is text.

31 / 60
body {
				background: white;
				color: contrast-color(white);
			}
			

This is some text.

32 / 60
body {
				background: darkred;
				color: contrast-color(darkred);
			}
			

This is some text.

Speaker notes

Theming? What if variable?

33 / 60
body {
				background: yellow;
				color: contrast-color(yellow);
			}
			

This is some text.

Speaker notes

Versatile, resilient CSS.

34 / 60

This is some text. This is some text.

Speaker notes

Doesn’t guarantee 4.5:1 ratio required by WCAG AA.

Only Black or White. More control in future.

No font-size accounting. No image or transparency support.

35 / 60

Invoker Commands

36 / 60

This dialog is controlled via JavaScript.

Speaker notes

JavaScript demo first.

37 / 60
<button id="open-btn">Open Dialog</button>
			
			<dialog id="example-dialog">
				<p>This dialog is controlled via JavaScript.</p>
				<button id="close-btn">Close</button>
			</dialog>
			
const dialog = document.getElementById("example-dialog");
			const openBtn = document.getElementById("open-btn");
			const closeBtn = document.getElementById("close-btn");
			
			openBtn.addEventListener("click", () => dialog.showModal());
			closeBtn.addEventListener("click", () => dialog.close());
			
38 / 60
<button commandfor="example-dialog" command="show-modal">Open Dialog</button>
			
			<dialog id="example-dialog">
				<p>This dialog is controlled natively via invoker commands.</p>
				<button commandfor="example-dialog" command="close">Close</button>
			</dialog>
			
39 / 60

This dialog is controlled natively via invoker attributes.

Speaker notes

No JavaScript. No waiting for load. No inactive button.

40 / 60

Scroll Driven Animations

41 / 60

Speaker notes

Note animation stops if I stop scrolling.

42 / 60
.box {
				animation: scale-up;
				animation-timeline: view();
			}
			
			@keyframes scale-up {
				0% {
					transform: scale(0.3);
					opacity: 0.5;
				}
				100% {
					transform: scale(1.5) rotate(360deg);
					opacity: 1;
					background: #ff0077;
				}
			}
			

Speaker notes

view() - nearest ancestor scroll container. Progress bar as scroll.

43 / 60

Scroll Triggered Animations

44 / 60
45 / 60
.box {
				animation: scale-up 2s both;
				timeline-trigger: --view-trigger view();
				animation-trigger: --view-trigger play-forwards;
			}
			
			@keyframes scale-up {
				from {
					transform: scale(0.3);
					opacity: 0.2;
				}
				to {
					opacity: 1;
					transform: scale(1.5) rotate(360deg);
					background: #ff0077;
				}
			}
			

Speaker notes

Intersection Observer API

46 / 60

View Transitions

47 / 60

Flip

This page has a ‘flip’ transition.

48 / 60

Dissolve

This page has a ‘dissolve’ transition.

49 / 60

Iris

This page has a ‘iris’ transition.

50 / 60

Barn

This page has a ‘barn’ transition.

51 / 60

Spin

This page has a ‘spin’ transition.

52 / 60
@view-transition {
				navigation: auto;
			}
			

Speaker notes

Notice slide as I go to next page.

53 / 60
@keyframes slide-out {
				to {
					transform: translateX(-100vw);
				}
			}
			
			@keyframes slide-in {
				from {
					transform: translateX(100vw);
				}
			}
			
54 / 60
::view-transition-old(root) {
				animation: slide-out 0.4s both;
			}
			
			::view-transition-new(root) {
				animation: slide-in 0.4s both;
			}
			

Speaker notes

Pseudo Elements

55 / 60

This is some text

56 / 60

This is some text!

57 / 60

This is some text!

view-transition-name: text-example;
			
58 / 60

Wrap Up

Speaker notes

  • Balancing - text and flex
  • corner-shape()
  • text-box trim
  • sibling-count() and sibling-index()
  • color-mix()
  • contrast-color()
  • Invoker Commands
  • Scroll Driven/Triggered Animations
  • View Transitions
59 / 60
60 / 60

https://vale.rocks

Speaker notes

Slides. Supplementary materials. Details about me.