Bram.us https://www.bram.us A rather geeky/technical weblog, est. 2001, by Bramus Tue, 26 Nov 2024 10:26:12 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 Experiment: Automatically triggered View Transitions with MutationObserver https://www.bram.us/2024/11/25/experiment-automatically-triggered-view-transitions-with-mutationobserver/ https://www.bram.us/2024/11/25/experiment-automatically-triggered-view-transitions-with-mutationobserver/#respond <![CDATA[Bramus!]]> Mon, 25 Nov 2024 13:36:29 +0000 <![CDATA[Original Content]]> <![CDATA[mutationobserver]]> <![CDATA[view transitions]]> https://www.bram.us/?p=34911 <![CDATA[A MutationObserver and document.startViewTransition love story.]]> <![CDATA[

Instead of adding document.startViewTransition at various places in your JS, use a MutationObserver to watch for DOM mutations. In the Observer’s callback undo the original mutation and reapply it, but this time wrapped in a View Transition.

~

# The need for automatic View Transitions

Today on BlueSky, Cory LaViska wondered the following about Same-Document View Transitions:

I wish I could opt certain elements in to View Transitions so all DOM modifications would just work without having to wrap with document.startViewTransition() 🤔

— Cory LaViska (@cory.laviska.com) November 25, 2024 at 3:11 AM

This is a very valid feature request, and also something that my colleague Adam and I have needed ourselves before. Check the following demo which triggers a View Transition in response to a radio button being checked.

See the Pen
Radiento – Bento Radio Group Carousel thing
by Adam Argyle (@argyleink)
on CodePen.

In order to make it work, you need to hijack the radio selection, undo it, and then re-apply it but this time wrapped in a View Transition.

The code powering this is the following:

document.querySelectorAll('.item input').forEach(($input) => {
	// @note: we listen on click because that happens *before* a change event.
	// That way we can prevent the input from getting checked, and then reapply
	// the selection wrapped in a call to `document.startViewTransition()`
	$input.addEventListener('click', async (e) => {
		if (!document.startViewTransition) return;

		e.preventDefault();

		document.startViewTransition(() => {
			e.target.checked = true;
		});
	});
});

Like Cory said, it would be nice if this worked without any extra code. What if you didn’t need to hijack the click event nor needed to riddle your JS-logic with calls to document.startViewTransition, but had something that allows you to say: “When this changes, do it with a Same-Document View Transition”? That’d be very nice, easy, and robust.

💡 This feature is something that is on the Chrome team’s back-of-the-backlog. We are roughly thinking of a CSS property or something like that to opt-in to it, and are tentatively calling this potential feature “Declarative View Transitions”. Don’t get your hopes up for this just yet, as there are a bunch of other features – not specifically related to View Transitions – that have a much higher priority.

~

# Auto-trigger a View Transition with MutationObserver

Sparked by Cory’s request I created a POC that tries to give an answer to the problem. The starting point I used is the following demo which allows you to add and remove cards to a list.

See the Pen
Add/Remove Cards with View Transitions (using view-transition-classs)
by Bramus (@bramus)
on CodePen.

Without View Transitions, the core of that demo is the following:

document.querySelector('.cards').addEventListener('click', e => {
	if (e.target.classList.contains('delete-btn')) {
			e.target.parentElement.remove();
	}
})

document.querySelector('.add-btn').addEventListener('click', async (e) => {
	const template = document.getElementById('card');
	const $newCard = template.content.cloneNode(true);
	$newCard.firstElementChild.style.backgroundColor = `#${ Math.floor(Math.random()*16777215).toString(16)}`;
	document.querySelector('.cards').appendChild($newCard);
});

Instead of adjusting the code above to include View Transitions – as I have done in the previous embed – I resorted to adding a MutationObserver to the code. The MutationObserver is used to execute a callback when it observes a DOM change. In the callback I have it set to automatically undo+reapply the mutation that was done. For example, when a card gets added to the list, I immediately remove that newly added element and then re-add it wrapped in document.startViewTransition. This works because MutationObserver callbacks are queued as microtasks, which can block rendering.

const observer = new MutationObserver(async (mutations) => {
	for (const mutation of mutations) {
		// A node got added
		if (mutation.addedNodes.length) {
			const $li = Array.from(mutation.addedNodes).find(n => n.nodeName == 'LI');
		
			// …

			// Undo the addition, and then re-added it in a VT
			$li.remove();
			const t = document.startViewTransition(() => {
				mutation.target.insertBefore($li, mutation.nextSibling);
			});

			// …
		}
	}
});
observer.observe(document.querySelector('.cards'), {
	childList: true,
	characterData: false,
});

With that code in place, the snapshotting process for View Transitions is able to capture the old and new states properly when a card was added: one without the newly added element and one with the newly added element.

A similar thing is done for a card being removed: it immediately gets re-added, and only then it gets removed through a View Transition. Also in place is some logic to prevent the callback from blocking rendering indefinitely because the call $li.remove(); done in the callback would trigger a new mutation to happen.

Combined, the result is this:

See the Pen
Automatically triggered View Transitions with MutationObserver
by Bramus (@bramus)
on CodePen.

~

# Not tackled by MutationObserver

Not tackled in this POC are changes like radio buttons getting checked. This because those changes are not changes that are observable by a MutationObserver: it is a DOM property of the element that changes, not an attribute. To tackle that use-case, you can use something like my StyleObserver to trigger an observable change when the checkbox/radio changes to :checked. Problem there, though, is that StyleObserver changes fire too late: because the changes fire after rendering, you get a glitch of 1 frame when reapplying the change. See the following embed, in which I adjusted Adam’s Bento demo to use @bramus/style-observer to trigger the View Transition:

See the Pen
Radiento – Bento Radio Group Carousel thing
by Bramus (@bramus)
on CodePen.

Ideally, we’d either need a StyleObserver that triggers before rendering, or something like an extension to MutationObserver that also allows you to monitor property changes.

Also not covered are batched updates – such as elements getting removed in once place and added in a new place. In the demo above I have worked around this by manually grouping the mutations into pairs before handling them as one changeset.

~

# Spread the word

Feel free to repost one of my posts on social media to give them more reach, or link to the blogpost yourself one way or another 🙂

~

]]>
https://www.bram.us/2024/11/25/experiment-automatically-triggered-view-transitions-with-mutationobserver/feed/ 0
Supercharge Web UX with View Transitions (2024.10.18 @ React Brussels) https://www.bram.us/2024/11/17/supercharge-web-ux-with-view-transitions-react-brussels/ https://www.bram.us/2024/11/17/supercharge-web-ux-with-view-transitions-react-brussels/#respond <![CDATA[Bramus!]]> Sun, 17 Nov 2024 10:44:26 +0000 <![CDATA[Original Content]]> <![CDATA[public speaking]]> <![CDATA[view transitions]]> https://www.bram.us/?p=34905 <![CDATA[Slides + recording of the talk “Supercharge Web UX with View Transitions” I gave at React Brussels 2024]]> <![CDATA[

Me, on stage.

Last month I spoke at React Brussels and gave a talk “Supercharge Web UX with View Transitions”

~

Table of Contents

~

# The Talk

The talk I gave is a full-length talk of a little over 30 minutes.

Tired of disjointed web apps? View Transitions are the game-changer you’ve been waiting for. Whether your app is single or multi-page, this powerful API lets you create seamless, native-like experiences that captivate users. Join me as I dive into the world of View Transitions, showing you how to replace jarring page loads with elegant transitions. Learn to harness the flexibility of CSS and the power of JavaScript to customize transitions and create a truly unique experience. If you’re ready to take your web apps to the next level, this talk is a must-attend.

~

# Slides

The slides of my talk are up on slidr.io are embedded below:

These exported slides don’t contain any recordings of the demos included, but you can follow the link to check them out yourself. For the Same-Document View Transitions demos you will need Chrome 111+. For the Cross-Document View Transitions demos you need Chrome 126+.

~

# Recording/Video

This talk was recorded and is available for you to watch on YouTube. The video is also embedded below:

~

# Thanks!

Thanks to Aymen and Elian for inviting me to speak at this wonderful event. It was very well organized and everything – from my POC – went smooth. A pity the turnout wasn’t that great (but definitely not bad too!). It was also very heartwarming to see that not all talks focused on purely React itself and some of its libraries, but that some talks also covered things such as accessibility and progressive enhancement. A well balanced set of talks, delivered by some great speakers, is what I consider a great conference 🙂

~

💁‍♂️ If you are a conference or meetup organiser, don't hesitate to contact me to come speak at your event.

]]>
https://www.bram.us/2024/11/17/supercharge-web-ux-with-view-transitions-react-brussels/feed/ 0
Chrome Dark Mode Toggle v1.1 https://www.bram.us/2024/10/30/chrome-dark-mode-toggle-v1-1/ https://www.bram.us/2024/10/30/chrome-dark-mode-toggle-v1-1/#comments <![CDATA[Bramus!]]> Wed, 30 Oct 2024 07:21:30 +0000 <![CDATA[Original Content]]> <![CDATA[dark mode]]> <![CDATA[web preferences api]]> https://www.bram.us/?p=34897 <![CDATA[On top of a per-origin override, you can now set a Chrome-wide preference to have your OS in Dark Mode but all sites in Light Mode (or vice versa).]]> <![CDATA[

Yesterday I published a new version of my experimental Chrome Dark Mode Toggle extension. On top of a per-origin override, you can now set a Chrome-wide preference to have your OS in Dark Mode but all sites in Light Mode (or vice versa).

You can get the extension from the Chrome Web Store.

For a backstory behind the why and how of this extension, go read the original announcement post.

]]>
https://www.bram.us/2024/10/30/chrome-dark-mode-toggle-v1-1/feed/ 1
Scroll-driven animated card stack with scroll snap events https://www.bram.us/2024/10/13/scroll-driven-animated-card-stack-with-scroll-snap-events/ https://www.bram.us/2024/10/13/scroll-driven-animated-card-stack-with-scroll-snap-events/#comments <![CDATA[Bramus!]]> Sun, 13 Oct 2024 12:43:09 +0000 <![CDATA[Original Content]]> <![CDATA[css]]> <![CDATA[scroll-driven animations]]> https://www.bram.us/?p=34877 <![CDATA[Dissecting and reworking a very nice demo by Paul Noble.]]> <![CDATA[
Recording of Paul’s demo

Dissecting and reworking a very nice demo by Paul Noble.

~

Card Stack Demo

Paul Noble created an AMAZING scroll-driven animations demo in which you can drag cards from a card stack. As he describes it:

Card stack using scroll-driven animation w/ snapping. Just a few lines of JS, zero dependencies.

Try it out (in Chrome) right here:

See the Pen
Scroll-driven animated card stack with scroll snap events.
by Paul Noble (@paulnoble)
on CodePen.

The logic/math used for the stack is based on this thread by Nate Smith

~

💁‍♂️ Unfamiliar with Scroll-Driven Animations? Don’t worry, I’ve created a free video course “Unleash the Power of Scroll-Driven Animations” which teaches you all there is to know about Scroll-Driven Animations.

Poster frame of the fist episode of the series

Go check it out to become an expert in Scroll-Driven Animations!

~

Dissecting the code

On social media I already shared (Twitter, Mastodon) how Paul built it:

Invisible Scroller
The first clever thing Paul is doing there is using an invisible scroller laid on top of the stack of cards. This scroller gets a ScrollTimeline named --scroll-timeline attached to it.
Hoisting the Timeline
To make the .card-stack see the --scroll-timeline, it gets hoisted using timeline-scope on the body. Any child of the body – including .card-stack – can therefore use that --scroll-timeline.
Scroll-Snapping
To make the cards always show at the center, CSS scroll-snapping is used.
Snap Events
In his demo, Paul also uses the new scrollsnapchange event to let the markup know which card has snapped. This is propagated through the data-active-index attribute on the main element.
Custom animations based on which card has snapped
Based on the data-active-index attribute, different animations are attached to the cards: the snapped card gets an active animation – which rotates in 3D around the stack – and the non-snapped cards get an inactive animation – which rotates the card around its base.

~

Remixing the demo

Paul’s demo is amazing but also hard to read because the Sass code uses quite some some math to generate keyframes for each card. As hinted on social media I was quite sure that the effect can also be done using shared keyframes for each card. To attach the keyframes to a single .card a ViewTimeline on the linked .scroll-item can be used, and using animation-range it’s possible to limit when the animation should run.

Yesterday evening I put my money where my mouth is and took my idea for a spin. The result is not 100% perfect – there are some 3D stacking issue, most likely I need to tweak the animation-ranges a bit more – but the result comes pretty close to the original:

See the Pen
Scroll-driven animated card stack with scroll snap events (Vanilla)
by Bramus (@bramus)
on CodePen.

While at it, I also reworked the scrollSnapChange logic to use event.snapTargetInline and by also providing a fallback using IntersectionObserver in browsers with no support for the Snap Events.

~

]]>
https://www.bram.us/2024/10/13/scroll-driven-animated-card-stack-with-scroll-snap-events/feed/ 1
CSSNestedDeclarations is coming to all browsers to improve CSS Nesting! https://www.bram.us/2024/10/08/cssnesteddeclarations-is-coming-to-all-browsers-to-improve-css-nesting/ https://www.bram.us/2024/10/08/cssnesteddeclarations-is-coming-to-all-browsers-to-improve-css-nesting/#respond <![CDATA[Bramus!]]> Tue, 08 Oct 2024 13:15:03 +0000 <![CDATA[Elsewhere]]> <![CDATA[css]]> <![CDATA[css nesting]]> <![CDATA[css object model]]> <![CDATA[link]]> https://www.bram.us/?p=34866 <![CDATA[CSS nesting just got a whole lot better!]]> <![CDATA[

I have a new article up on web.dev, about CSSNestedDeclarations which is coming to all browsers.

To fix some weird quirks with CSS nesting, the CSS Working Group resolved to add the CSSNestedDeclarations interface to the CSS Nesting Specification. With this addition, declarations that come after style rules no longer shift up, among some other improvements.

These changes are available in Chrome from version 130 and are ready for testing in Firefox Nightly 132 and Safari Technology Preview 204.

Besides writing the post, I had lots of fun building this CSSRule debugger for this blogpost. It shows you what goes on behind the scenes and how your CSS gets interpreted by the CSS Engine.

Here’s a comparison of Chrome without and with CSSNestedDeclarations support. The version with CSSNestedDeclarations support clearly is better.

Screenshot of the CSSRule Debugger in Chrome 129, which has no CSSNestedDeclarations support: in the parsed CSS the declarations got shifted up, amongst other things.
Screenshot of the CSSRule Debugger in Chrome 130, which has CSSNestedDeclarations support: the parsed CSS is the same as the input CSS thanks to CSSNestedDeclarations which you can see in the serialized CSS section.

I cannot help but stress that this is a change that is part of the CSS Nesting spec and is one that is coming to all engines. Firefox Nightly 132 is passing all tests, and with 8/11 subtests passing Safari Technology Preview 204 still has a little bit of cleaning to do before it can ship this.

Read “CSS nesting improves with CSSNestedDeclarations” →

]]>
https://www.bram.us/2024/10/08/cssnesteddeclarations-is-coming-to-all-browsers-to-improve-css-nesting/feed/ 0
Feature detect Style Queries Support in CSS https://www.bram.us/2024/10/06/feature-detect-style-queries-support-in-css/ https://www.bram.us/2024/10/06/feature-detect-style-queries-support-in-css/#respond <![CDATA[Bramus!]]> Sun, 06 Oct 2024 21:48:34 +0000 <![CDATA[Original Content]]> <![CDATA[css]]> <![CDATA[feature detection]]> <![CDATA[style queries]]> https://www.bram.us/?p=34844 <![CDATA[Awaiting browser support for at-rule(), here’s how you do it.]]> <![CDATA[

The other day on X, Adam Wathan wondered how to feature detect (Custom Property) Style Queries. While in theory you could use @supports at-rule() for this, in practice you can’t because it has no browser support (… yet).

Drawing inspiration from my previous post on how to detect support for @starting-style, I came up with a similar method to detect support for Style Queries: try actively using them and respond to that.

~

# The Code

If you are here for just the code, here it is:

html {
  --sentinel: 1;
}

@container style(--sentinel: 1) {
  body {
    --supported: ; /* Space Toggle */
  }
}

With this you get a Space Toggle for you to use in your code.

Before you tl;dr this post, you might still want to read The problem with Safari 18 section …

~

# How it works

The code works by actively trying to use a Style Query. It sets a --sentinel property on the root element and then lets the body element respond to it – using a Style Query – trying to declare the --supported custom property.

When Style Queries are supported, the result will be a --supported custom property that is set to an empty value. In browsers with no Style Queries support, the --supported property will be the guaranteed-invalid value (of initial). Yes, a Space Toggle.

With that --supported Space Toggle in place, you can then use it in your CSS:

body {
  --bg-if-support: var(--supported) green;
  --bg-if-no-support: var(--supported, red);
  background: var(--bg-if-support, var(--bg-if-no-support));
}

~

# Demo

The demo below uses the code shown earlier:

See the Pen
Feature Detect Style Queries (1/2)
by Bramus (@bramus)
on CodePen.

If you’re using Safari 18, you might notice it doesn’t work as expected …

~

# The problem with Safari 18

While Safari 18 does come with support for (Custom Property) Style Queries, you might have noticed the previous demo does not work in it.

The culprit: A bug in which the root element cannot be a container in Safari 18 – https://bugs.webkit.org/show_bug.cgi?id=271040.

To work around this bug, you need to move everything down one level in your DOM tree. Like so:

body {
  --sentinel: 1;
}

@container style(--sentinel: 1) {
  body > * {
    --supported: ; /* Space Toggle */
  }
}

This means you can’t use --supported to conditionally style the body element itself, which might be OK for your use-case.

☝️ The bug has been fixed in Safari Technology Preview 204 and should be included in Safari 18.1 when released.

~

# Safari 18-friendly demo

Here’s a demo of the code that also works in Safari. Note that it can’t be used to style the body element itself.

See the Pen
Feature Detect Style Queries (2/2)
by Bramus (@bramus)
on CodePen.

~

# Spread the word

Feel free to repost one of the posts from social media to give them more reach, or link to this post from your own blog.

~

]]>
https://www.bram.us/2024/10/06/feature-detect-style-queries-support-in-css/feed/ 0
Benchmarking the performance of CSS @property https://www.bram.us/2024/10/03/benchmarking-the-performance-of-css-property/ https://www.bram.us/2024/10/03/benchmarking-the-performance-of-css-property/#respond <![CDATA[Bramus!]]> Thu, 03 Oct 2024 13:03:14 +0000 <![CDATA[Elsewhere]]> <![CDATA[css]]> <![CDATA[link]]> <![CDATA[performance]]> https://www.bram.us/?p=34834 <![CDATA[With @​property now being Baseline Newly Available, I thought it’d be a good time benchmark the impact – if any – it has on the performance of your CSS. When starting to use a new CSS feature it’s important to understand its impact on the performance of your websites, whether positive or negative. With @property … ]]> <![CDATA[

With @​property now being Baseline Newly Available, I thought it’d be a good time benchmark the impact – if any – it has on the performance of your CSS.

When starting to use a new CSS feature it’s important to understand its impact on the performance of your websites, whether positive or negative. With @property now in Baseline this post explores its performance impact, and things you can do to help prevent negative impact.

For this I built and open sourced the “CSS Selector Benchmark” project which I have been working on for some time now.

To benchmark the performance of CSS we built the “CSS Selector Benchmark” test suite. It is powered by Chromium’s PerfTestRunner and benchmarks the performance impact of CSS. This PerfTestRunner is what Blink (= Chromium’s underlying rendering engine) uses for its internal performance tests.

The runner includes a measureRunsPerSecond method which is used for the tests. The higher the number of runs per second, the better.

The created benchmarks for @property specifically measure how fast Blink can handle a Style Invalidation and the subsequent Recalculate Style task. This was tested with both registered and unregistered custom properties, as well as regular properties.

Read “Benchmarking the performance of CSS @property” on web.dev →
Check out “css-selector-benchmark” on GitHub →

]]>
https://www.bram.us/2024/10/03/benchmarking-the-performance-of-css-property/feed/ 0
Solved by CSS Scroll-Driven Animations: hide a header when scrolling down, show it again when scrolling up. https://www.bram.us/2024/09/29/solved-by-css-scroll-driven-animations-hide-a-header-when-scrolling-up-show-it-again-when-scrolling-down/ https://www.bram.us/2024/09/29/solved-by-css-scroll-driven-animations-hide-a-header-when-scrolling-up-show-it-again-when-scrolling-down/#comments <![CDATA[Bramus!]]> Sun, 29 Sep 2024 12:32:08 +0000 <![CDATA[Original Content]]> <![CDATA[demo]]> <![CDATA[scroll-driven animations]]> https://www.bram.us/?p=34813 <![CDATA[By adding a long transition-delay to a CSS property under certain conditions (which you can do using a Style Query), you can persist its value.]]> <![CDATA[
Recording of Fabrizio’s demo

By adding a long transition-delay to a CSS property under certain conditions (which you can do using a Style Query), you can persist its value after the condition no longer applies.

~

Detecting the Scroll-Direction with CSS Scroll-Driven Animations

One of the demos that I built as part of the “Solved by CSS Scroll-Driven Animations: Style an element based on the active Scroll Direction and Scroll Speed” article is a header element that hides itself on scroll.

Here’s the demo I’m talking about: as you scroll up or down, the header hides itself. When idling, it comes back into view. Check it out using a Chromium-based browser, as those – at the time of writing – are the only browsers to support Scroll-Driven Animations.

See the Pen
CSS scroll-direction detection with Scroll-Driven Animations with moving header
by Bramus (@bramus)
on CodePen.

In the code of that demo there are few CSS variables that are either 0 or 1 when scrolling – or not-scrolling – when scrolling in a certain direction. The CSS looks like this:

--when-scrolling: abs(var(--scroll-direction));
--when-not-scrolling: abs(var(--when-scrolling) - 1);

--when-scrolling-up: min(abs(var(--scroll-direction) - abs(var(--scroll-direction))), 1);
--when-scrolling-down: min(var(--scroll-direction) + abs(var(--scroll-direction)), 1);

--when-scrolling-down-or-when-not-scrolling: clamp(0, var(--scroll-direction) + 1, 1);
--when-scrolling-up-or-when-not-scrolling: clamp(0, abs(var(--scroll-direction) - 1), 1);

💁‍♂️ If you want to know exactly how it works, go check out episode 9 of the free video course “Unleash the Power of Scroll-Driven Animations” I made, which teaches you all there is to know about Scroll-Driven Animations. The episode is also right here:

~

The transition-delay trick

As I had noted in the article, these variables are fleeting. From the moment you stop scrolling, all those variables – except --when-not-scrolling – become 0 again. Therefore, the header in the example will reveal itself again once you stop scrolling. A better experience would be to hide the header when scrolling down and to keep it that way until the moment you scroll up again. However, I didn’t find a solution to do that back then.

Fast forward to a few months later. While at CSS Day 2024, Schepp shared that he found way to make those custom properties “sticky”. His trick? Adding a long transition-duration to the properties when scrolling in a certain direction.

In the following snippet, the transition is stalled indefinitely when idling. That way, the --scroll-* custom properties will retain their value until you start scrolling again.

@container style(--scroll-direction: 0) {
   header {
      transition-delay: calc(infinity * 1s);  
   }
}

~

Putting it all together

Unfortunately I hadn’t found the time to actively use Schepp’s suggestion in the hiding header demo ever since we discussed it (but I did use it for my @starting-style feature detection technique).

Fast forward to just last week, and Fabrizio Calderan reached out on X to share his “Hide on Scroll Down, Show on Scroll Up Header” CodePen

See the Pen
Hide on Scroll Down, Show on Scroll Up Header
by Fabrizio Calderan (@fcalderan)
on CodePen.

Fabrizio came to creating the same trick Schepp had suggested to me, by relying on a long transition-behavior which he sets in a Style Query:

@container style(--scroll-direction: 0) {
   /* Scroll is idle, so we keep the current header position by setting the transition-delay to infinity */
   header {
      transition-delay: calc(infinity * 1s);  
   }
}


@container style(not (--scroll-direction: 0)) {
   /* page is scrolling: if needed, the animation of the header should run immediately */
   header {
      transition-delay: 0s;  
   }
}

@container style(--scroll-direction: -1) {
   /* Scrolling up, so we must reveal the header */
   header {
      --translate: 0;
   }
}

@container style(--scroll-direction: 1) { 
   /* Scrolling down, so we must hide the header */
   header {
      --translate: -100%;
   }
}

Nice one, Fabrizio!

When trying it out, you’ll notice it still is not 100% perfect though, as you can end up in situation where the header remains hidden when starting a scroll down immediately followed by a scroll up. This confirms to me that there still is a need to have the scroll-direction be exposed by the browser itself, instead of needing to rely on a hack powered by Scroll-Driven Animations. The current line of thinking is to use a Scroll-State Style Query for this.

~

Spread the word

Feel free to repost one of the posts from social media to give them more reach, or link to this post from your own blog.

~

]]>
https://www.bram.us/2024/09/29/solved-by-css-scroll-driven-animations-hide-a-header-when-scrolling-up-show-it-again-when-scrolling-down/feed/ 1
The CSS Podcast 089: View Transitions https://www.bram.us/2024/09/26/the-css-podcast-089-view-transitions/ https://www.bram.us/2024/09/26/the-css-podcast-089-view-transitions/#respond <![CDATA[Bramus!]]> Thu, 26 Sep 2024 20:49:00 +0000 <![CDATA[Elsewhere]]> <![CDATA[link]]> <![CDATA[podcast]]> <![CDATA[view transitions]]> https://www.bram.us/?p=34807 <![CDATA[Last week I joined my colleagues Adam and Una on The CSS Podcast to talk about View Transitions.]]> <![CDATA[

Last week I joined my colleagues Adam and Una on The CSS Podcast. I was brought on to talk about View Transitions, a feature I’m doing the DevRel work for at Google.

In this episode Una and Adam bring on an esteemed guest Bramus, who brings us deep knowledge on View Transitions. These are easy to get started with but difficult to master, but not with Bramus here to teach us. He’ll be covering introductory to advanced API features and a big bag of examples and demos.

You can watch the episode on YouTube, which I have embedded below:

You can also listen to it using your favorite podcasting app.

]]>
https://www.bram.us/2024/09/26/the-css-podcast-089-view-transitions/feed/ 0
Observing Style Changes (2024.09.25 @ devs.gent) https://www.bram.us/2024/09/25/observing-style-changes-2024-09-25-devs-gent/ https://www.bram.us/2024/09/25/observing-style-changes-2024-09-25-devs-gent/#respond <![CDATA[Bramus!]]> Wed, 25 Sep 2024 21:10:54 +0000 <![CDATA[Original Content]]> <![CDATA[css]]> <![CDATA[public speaking]]> https://www.bram.us/?p=34802 <![CDATA[Slides of the talk “Observing Style Changes” I gave at the September 2024 meetup of devs.gent at the Lemon Ghent offices.]]> <![CDATA[

Me, on stage. Photo by devs.gent.

Today I gave a talk at the September 2024 devs.gent meetup on how to observe and respond to Style Changes.

~

Table of Contents

~

# The Talk

The talk I gave was about half an hour and covered my journey into building @bramus/style-observer

A shortcoming of MutationObserver is that it cannot be used to subscribe to value changes of CSS properties.

While you could resort to requestAnimationFrame and getComputedStyle to plug that hole (which you shouldn’t), there is a more performant way to achieve this: leverage the power of CSS transitions in combination with the fairly recent transition-behavior: allow-discrete. With it, you can set up JavaScript callbacks to respond to changes in computed values of CSS properties – including Custom Properties.

This is basically a talkified version of this blog post.

~

# Slides

The slides of my talk are up on slidr.io are embedded below:

These exported slides don’t contain any recordings of the demos included, but you can follow the links on the slides to check them out yourself.

~

# Recording/Video

This talk was recorded. Once the recording is released, I’ll update this post to include the embed.

~

# Thanks!

Thanks again to Bert, Elian, and Freek for having me. Always a pleasure to speak at a local meetup and meet new and old friends. Also a big kudos to Lemon for hosting, offering food and beverages, and providing a crew to record the talks.

~

💁‍♂️ If you are a conference or meetup organiser, don't hesitate to contact me to come speak at your event.

]]>
https://www.bram.us/2024/09/25/observing-style-changes-2024-09-25-devs-gent/feed/ 0