Sign in

Jan Nicklas

@jantimon.bsky.social
794 followers 1.6K following 108 posts

living in Switzerland 🇨🇭 mainly working on typescript, css and compiler related frontend topics github.com/jantimon

PostsRepliesMedia
Jan Nicklas @jantimon.bsky.social · 06/10/2026
nowadays css-in-js is as fast as css modules and easier to maintain jantimon.github.io/css-in-js-be...
jantimon.github.io
CSS-in-JS benchmarks
styled-components, Emotion, Goober, next-yak, StyleX, Panda, Tailwind — identical workloads, measured SSR + client cost.
000
Reposted by Jan Nicklas
Nilesh Prajapati @nileshprajapati.com · 17/09/2026
Responsive iframes in Chrome 154 #CSS frame-sizing 🤔
developer.chrome.com
Responsive iframes in Chrome 154  |  Blog  |  Chrome for Developers
Chrome 154 adds support for responsively-sized iframes, letting an iframe size itself based on the intrinsic size of its embedded document.
082
Jan Nicklas @jantimon.bsky.social · 16/09/2026
Unfortunately a text-box solution would require an additional dom element 🤷
000
Jan Nicklas @jantimon.bsky.social · 16/09/2026
why didn't textbox-trim work for you?
110
Reposted by Jan Nicklas
Kevin Powell @kevinpowell.co · 26/08/2026
Scroll-triggered animations that fire once and stay without any JavaScript. The trick is using animation-play-state to pause the animation when it's out of view. www.youtube.com/watch?v=onra...
youtube.com
Nobody told me CSS could do this
YouTube video by Kevin Powell
5566
Jan Nicklas @jantimon.bsky.social · 24/08/2026
Oh wow BorisChiou is already looking into it - that was quick
010
Jan Nicklas @jantimon.bsky.social · 24/08/2026
the bug can be seen on all demos with `max` in the name on jantimon.github.io/demo-tile-ca... is it maybe this 8 month old issue? bugzilla.mozilla.org/show_bug.cgi...
bugzilla.mozilla.org
2006260 - Compositor animation support for timeline ranges
NEW (nobody) in Core - CSS Transitions and Animations. Last updated 2026-08-23.
120
Jan Nicklas @jantimon.bsky.social · 24/08/2026
@webdevs.firefox.com in nightly this animation timeline based carousel navigation is broken are these kind of bugs already known (it is nightly after all) or is it new?
152
Reposted by Jan Nicklas
Patrick Brosset @patrickbrosset.com · 23/08/2026
Great news! The CSS sibling-count() and sibling-index() functions are now Baseline Newly Available! I.e implemented in all major browsers.
web-platform-dx.github.io
sibling-count() and sibling-index() - Web platform features explorer
The sibling-count() and sibling-index() CSS functions return integers that are useful to style elements based on their positions among siblings or on the number of siblings, for example as part of a c...
413830
Jan Nicklas @jantimon.bsky.social · 21/08/2026
I tried to show very basic and simple examples For me CSS should provide the basic building blocks to help devs building amazing experiences If you like we can setup a meeting and I'll try to explain to you problems we face and why we structure, organize and bundle our code the way we do
110
Jan Nicklas @jantimon.bsky.social · 21/08/2026
Yes that would probably solve a lot of problems That would also unblock bundlers to optimize and split chunks even for code where injection order matters today Do you mean sth like this?
layers.css
@layer reset, [base, special], utilities;
base.css
@layer base {
  .btn { background: SlateBlue; color: white }

  .btn:disabled {
    background: Gainsboro;   /* (0,2,0) */
    color: DimGray;
    cursor: not-allowed;
  }
}
special.css
@layer special {
  .btn-hero { background: Crimson }   /* (0,1,0) */
}
markup
<button class="btn btn-hero" disabled>Add to cart</button>layers.css
@layer reset, [base, special, home], utilities;
base.css
@layer base {
  .btn { width: auto }

  @media (max-width: 700px) {
    .btn.btn { width: 100% }   /* (0,2,0) */
  }
}
special.css
@layer special {
  .btn-hero { width: 60% }   /* (0,1,0) */
}
home.css
@layer home {
  .btn-tiny { width: 50% }   /* (0,1,0) */

  @media (max-width: 700px) {
    .btn-tiny.btn-tiny { width: 50% }   /* (0,2,0) */
  }
}
000
Jan Nicklas @jantimon.bsky.social · 20/08/2026
For the third example - lets say another team is asked to build a new variant for the home page The complexity to solve this with layers raises here already for a button with a single width property in this example Imagine how hard it becomes for a more realistic case like a carousel
110
Jan Nicklas @jantimon.bsky.social · 20/08/2026
I really like the idea of margin-trim Here margin was just a simplified easy to understand example using margin-trim but there are many more :first-child cases
100
Reposted by Jan Nicklas
Firefox for Web Developers @webdevs.firefox.com · 19/08/2026
CSS text-box is newly baseline, and it's solves a common text layout issue. Here's how it works:
1234858
Reposted by Jan Nicklas
Dave Rupert @davatron5000.bsky.social · 19/08/2026
🚀 I made a smol ~2kb syntax highlighter that uses the CSS `::highlight()` API. davatron5000.github.io/microlighter/
davatron5000.github.io
MicroLighter - A zero-dep syntax highlighter
824442
Jan Nicklas @jantimon.bsky.social · 19/08/2026
layer and reyal don't help us for bundled web applications both can not provide the granularity web developers need when working in component based design systems here are three examples which afaik are not solvable without hacks when using @layer:
base.css
@layer base {
  .btn { background: SlateBlue; color: white }

  .btn:disabled {
    background: Gainsboro;
    color: DimGray;
    cursor: not-allowed;
  }
}

special.css (unlayered)
.btn-hero { background: Crimson }

markup
<button class="btn btn-hero" disabled>Add to cart</button>@layer base {
  .stack > .item { margin-block: 12px }

  .stack > .item:first-child { margin-block-start: 0 }
  .stack > .item:last-child  { margin-block-end: 0 }
}

special.css (unlayered)
.stack-loose > .item { margin-block: 28px }

markup
<ul class="stack stack-loose">
  <li class="item">…</li>
</ul>base.css
@layer base {
  .btn { width: auto }

  @media (max-width: 700px) {
    .btn.btn { width: 100% }   /* (0,2,0) */
  }
}

special.css (unlayered)
.btn-hero { width: 60% }   /* (0,1,0) */

markup
<button class="btn btn-hero">Add to cart</button>
100
Jan Nicklas @jantimon.bsky.social · 18/08/2026
2018 I reached out to @fantasai about the missing css text feature that eventually became text-box-trim she was incredibly supportive and did an amazing job on the css spec now only 8 years later it is live in all 3 browsers!! 🎉 thanks to everyone involved!
lists.w3.org
Re: CSS Rhythmic Sizing from fantasai on 2018-10-23 (www-archive@w3.org from October 2018)
081
Jan Nicklas @jantimon.bsky.social · 14/08/2026
Really happy to hear! Thank you for looking into it
020
Reposted by Jan Nicklas
Anne van Kesteren @annevk.nl · 13/08/2026
Thank you for the excellent report! This is a known limitation of our current implementation and also impacts <input type=range>. Fixing it is somewhat involved, but I agree we should do it.
121
Reposted by Jan Nicklas
Bramus @bram.us · 12/08/2026
Native apps on iOS can handle things just fine, so the web could (and should) do too. bsky.app/profile/bram...
041
Jan Nicklas @jantimon.bsky.social · 12/08/2026
will it behave during touch scrolling like webkit? bsky.app/profile/jant...
200
Jan Nicklas @jantimon.bsky.social · 12/08/2026
Correct here is a native scroll capture - even horizontal movements won't steal the scroll
000
Jan Nicklas @jantimon.bsky.social · 12/08/2026
<input type="checkbox" switch style="touch-action: pan-y" /> wouldn’t you expect that this allows panning on the y axis? we got user feedback about broken scrolls because they unintentionally started their scroll on a switch checkbox and there seems to be no opt out
110
Jan Nicklas @jantimon.bsky.social · 12/08/2026
@annevk.nl I think <input type=checkbox switch> has an iOS bug: a touch starting on the switch can't scroll the page. the input swallows the touch then toggles on release css touch-action doesn't help and other form controls scroll fine bugs.webkit.org/show_bug.cgi...
240
Jan Nicklas @jantimon.bsky.social · 14/04/2026
@capt.dev do you have any time to look into the ESM relay topic again? I reworked the promise polyfill removal: github.com/facebook/rel... the relay-compiler rust fix could be reviewed independently: github.com/facebook/rel... if helpful I have time for a sync this week
010
Jan Nicklas @jantimon.bsky.social · 22/03/2026
@capt.dev hi I'm Jan frontend lead at Galaxus where we heavily use relay and relay is literally the last thing blocking us from going full ESM.. I'd love to work on the relay esm support myself just need your guidance to do it right could you please drop me a DM if you find some time?
130
Reposted by Jan Nicklas
Lars @webpro.nl · 10/03/2026
✂️ Knip v6.0.0-0 is out A new chapter has begun. 👇
try.venz.dev
Venz
Easy and accessible dataviz
3629
Jan Nicklas @jantimon.bsky.social · 17/02/2026
@jensimmons.bsky.social we need your help @⁠⁠media queries stopped working on our production page safari now requires a reload to trigger the media query after resize bugs.webkit.org/show_bug.cgi... Safari Version 26.3 (21623.2.7.11.6) & Safari TP the reproduction has no javascript only css:
0101
Jan Nicklas @jantimon.bsky.social · 29/01/2026
@ricky.fm I am looking for the correct way to merge two ref callbacks for example a text-field with a ref returned by a library like react-hook-form together with in view tracking we ran into bugs and tried to solve it with a hook: github.com/jantimon/rea... is this approach the right way to go?
screenshot of https://github.com/jantimon/react-use-ref-effect/blob/master/src/useMergeRefs.ts

highlights the tricky part: if one ref changes, others should not be affected

also highlights the part where reconcilation is directly triggered within react render
000
Jan Nicklas @jantimon.bsky.social · 19/11/2025
@danabra.mov we have accessibility problems with react because react does not allow using a HTML attribute which was already supported in IE10 do you maybe know anyone who might take a short look? github.com/facebook/rea...
github.com
Bug: autoFocus broken inside <dialog /> · Issue #23301 · facebook/react
React version: 17 and 18.0.0-rc.0-next-27b569969-20220211 Steps To Reproduce render <input /><input autoFocus /> inside <dialog /> execute the showModal() method of the dialog you will notice that ...
120
Jan Nicklas @jantimon.bsky.social · 01/10/2025
it makes sense to me that useEffectEvent solves only one thing and not two but still - could you please show an example of lost reactivity?
010
Jan Nicklas @jantimon.bsky.social · 21/09/2025
you were right! it took me some time to test all cases manually and migrated them to playwright - but it behaves exactly as you described github.com/jantimon/rea... I also ran the playwright tests with react-compiler and the results were quite impressive
110
Jan Nicklas @jantimon.bsky.social · 16/09/2025
I believe you are right Do you know why act might cause problems when testing useTransition? Maybe I should switch to playwright tests for this repo
110
Jan Nicklas @jantimon.bsky.social · 16/09/2025
You can clearly see that the modal backdrop is cut off
150
Jan Nicklas @jantimon.bsky.social · 16/09/2025
Here is Apple.⁠com struggling with these viewport bugs:
1100
Reposted by Jan Nicklas
Bramus @bram.us · 15/09/2025
Viewport behavior in Safari 26 is utterly broken. 🙄😭 Time to get Viewports into #Interop2026 because viewports on iOS have gotten only worse since I did the initial research in, *checks notes*, 2022 — github.com/web-platform...
Screenshot of Safari 26 in "tabs at the top" mode showing a webpage that is set to `viewport-fit=cover` and the dynamic toolbars scrolled away (minimized). The viewport is too short and the safe area insets are all wrong. Device: iPhone 13 Pro.Screenshot of Safari 26 in "tabs at the top" mode showing a webpage with the dynamic toolbars scrolled away (minimized). The viewport (blue box) is way too short and does not toch the very top of the screen. Device: iPhone 13 Pro.
814025
Jan Nicklas @jantimon.bsky.social · 16/09/2025
useTransition (without memo -> no fallback) github.com/jantimon/rea... useDeferredValue (without memo -> forces fallback) github.com/jantimon/rea...
100
Jan Nicklas @jantimon.bsky.social · 16/09/2025
here `isPending` is NOT RENDERED and does NOT force the suspense boundary into its fallback but in the second example the state is NOT RENDERED and DOES force suspense boundary into its fallback both the isPending and the count state changed - but only one forces suspense boundary fallbacks 😵‍💫
100
Jan Nicklas @jantimon.bsky.social · 16/09/2025
why is that memo not needed for isPending from useTransition()?
100
Jan Nicklas @jantimon.bsky.social · 16/09/2025
unfortunately the react compiler must be the first compile step.. that limits using compile time optimizations e.g. for css-in-js, i18n, … and the compiler is written in babel which makes it quite slow for large codebases
110
Jan Nicklas @jantimon.bsky.social · 15/09/2025
it's truly amazing that your memo trick works but who is supposed to understand this code 😄
120
Jan Nicklas @jantimon.bsky.social · 15/09/2025
here is a useDeferredValue example and unit test it shows that useDeferredValue has no effect at all and causes the Suspense barrier to render its fallback for me this does not match the documentation which says "useDeferredValue is a React Hook that lets you defer updating a part of the UI"
100
Jan Nicklas @jantimon.bsky.social · 15/09/2025
github.com/jantimon/rea...
github.com
react-hydration-rules/src/tests/SuspenseTriggerOnExternalStoreComponent.test.tsx at main · jantimon/react-hydration-rules
Comprehensive guide documenting React hydration and Suspense fallback behaviors during SSR - jantimon/react-hydration-rules
010
Jan Nicklas @jantimon.bsky.social · 10/09/2025
Here is something else what confuses me and where I also don't know what I don't know This is a component inside memo and I don't understand why its render function is called 30+ times in this example stackblitz.com/edit/vitejs-... Are there any docs which explain this behaviour?
the render function is called many many times - although its inside `memo` and it is only once in the tree

"react": "19.1.1",
"react-dom": "19.1.1"
020
Jan Nicklas @jantimon.bsky.social · 09/09/2025
Now that I invested more time I feel it is fine My problem was that I didn't know what I didn't know and where to start when Suspense caused CLS For example the docs say "non-blocking Transition update" - does that mean there are blocking Transition updates too? Maybe I was just confused by AI 😄
for the prompt "Does SSR with React lazy render the suspense fallback or the content of the lazy component?" 

Claude gives a very confusing answerfor the prompt "Does SSR with React lazy render the suspense fallback or the content of the lazy component?" 

Chat GPT gives a kind of okayish answer
120
Jan Nicklas @jantimon.bsky.social · 09/09/2025
Many thanks Ricky for the hints - you were absolutely right.. After removing the `isPending` part the useTransition test is no longer breaking the Suspense Fallback! I updated the text and adjusted the tests
100
Jan Nicklas @jantimon.bsky.social · 08/09/2025
@danabra.mov did I miss anything in github.com/jantimon/rea... ?
github.com
GitHub - jantimon/react-hydration-rules: Comprehensive guide documenting React hydration and Suspense fallback behaviors during SSR
Comprehensive guide documenting React hydration and Suspense fallback behaviors during SSR - jantimon/react-hydration-rules
4144
Jan Nicklas @jantimon.bsky.social · 26/08/2025
that could potentially speed up projects a lot - especially if those projects use babel on node_modules
110
Jan Nicklas @jantimon.bsky.social · 23/08/2025
We would be curios to track down cross file react context usages - but it seems to be quite hard to do because of custom hooks, lazy loaded components, lazy loaded hooks, styled components, …
000
Jan Nicklas @jantimon.bsky.social · 21/08/2025
I recently wrote something like react-scanner from scratch in rust using swc as parser (claude code helped a lot) it scanned 12.000 tsx files in under 1s and was a lot of fun to build i can share the code if it helps
100