{"id":10341,"date":"2026-07-07T10:09:39","date_gmt":"2026-07-07T15:09:39","guid":{"rendered":"https:\/\/master.dev\/blog\/?p=10341"},"modified":"2026-07-07T10:09:39","modified_gmt":"2026-07-07T15:09:39","slug":"boundary-aware-styling-in-css","status":"publish","type":"post","link":"https:\/\/master.dev\/blog\/boundary-aware-styling-in-css\/","title":{"rendered":"Boundary-Aware Styling in CSS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">There are times we might prefer specific styles for elements located near the edges of their containers or the screen. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Different colors, sizes, or rotations based on how close they are to the edge and which side of the container they are on. Instead of relying on class names, item counts, or sibling positions, we can achieve this with <em>a single CSS function<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>view()<\/code> CSS function is known for its use in scroll-driven animations, affecting elements based on their visibility within a scroll container. However, it can be <strong>used without involving any actual scrolling or motion effect<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This article shows you how to do that to create more adaptive interfaces based on their closeness to their container\u2019s boundaries.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_bNgWwmr\" src=\"\/\/codepen.io\/anon\/embed\/bNgWwmr?height=450&amp;theme-id=1&amp;slug-hash=bNgWwmr&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed bNgWwmr\" title=\"CodePen Embed bNgWwmr\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">How <code>view()<\/code> Works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>view()<\/code>&nbsp;function links an animation&#8217;s progress to its visibility within its scroll container. When we apply&nbsp;<code>animation-timeline: view()<\/code>, the browser tracks the position of the element relative to its nearest scrollable container. The animation progress goes like this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>0% Progress (Start)<\/strong>: Triggered the exact moment the top\/left\/leading edge of the element enters the visible boundary of the scrollport.<\/li>\n\n\n\n<li><strong>100% Progress (End)<\/strong>: Reached when the bottom\/right\/trailing edge of the element completely exits the opposite side of the scrollport.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Boundary-Aware Style on Static Elements<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s a group of elements that are arranged in a three-column grid.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>Contacts<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>Shipping information<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>Find a product<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-comment\">&lt;!-- more --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.card<\/span> {\n  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">16<\/span>, <span class=\"hljs-number\">111<\/span>, <span class=\"hljs-number\">235<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">I want the cards to have different colors based on their horizontal distribution in their container. So, first, we&nbsp;<strong>turn the cards\u2019 parent,<\/strong>&nbsp;<code>&lt;main&gt;<\/code><strong>, into a scroll container<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-group learn-more\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>How does an element become a scroll container?<\/strong>&nbsp;An element automatically turns into a scroll container when you apply one of these:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>overflow: scroll;<\/code><\/li>\n\n\n\n<li><code>overflow: auto;<\/code><\/li>\n\n\n\n<li><code>overflow: hidden;<\/code> (No scrollbars, but the content is scrollable programmatically)<\/li>\n<\/ul>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s update&nbsp;<code>&lt;main&gt;<\/code>&nbsp;to be a scroll container:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">main<\/span> {\n  <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If <code>&lt;main&gt;<\/code> doesn\u2019t become a scroll container, the <code>view()<\/code> function we\u2019ll later apply might take the <code>&lt;body&gt;<\/code> element as the nearest scroll container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To change the cards\u2019 colors, I\u2019ll use the <code>hue-rotate()<\/code> filter. This goes into a <code>@keyframes<\/code> declaration.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@keyframes<\/span> cr {\n  <span class=\"hljs-comment\">\/* Set the color range *\/<\/span>\n  <span class=\"hljs-selector-tag\">from<\/span> { <span class=\"hljs-attribute\">filter<\/span>: <span class=\"hljs-built_in\">hue-rotate<\/span>(<span class=\"hljs-number\">180deg<\/span>); }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use the keyframes animation on the cards with the <code>view(x)<\/code> timeline. <code>x<\/code> is the horizontal axis.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.card<\/span> {\n  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">16<\/span>, <span class=\"hljs-number\">111<\/span>, <span class=\"hljs-number\">235<\/span>);\n  <span class=\"hljs-attribute\">animation<\/span>: cr;\n  <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_azppMgP\" src=\"\/\/codepen.io\/anon\/embed\/azppMgP?height=520&amp;theme-id=1&amp;slug-hash=azppMgP&amp;default-tab=result\" height=\"520\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed azppMgP\" title=\"CodePen Embed azppMgP\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Another example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@property<\/span> --a {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">angle<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: 0<span class=\"hljs-selector-tag\">deg<\/span>;\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n}\n<span class=\"hljs-keyword\">@keyframes<\/span> cr {\n  <span class=\"hljs-selector-tag\">from<\/span> { <span class=\"hljs-attribute\">--a<\/span>: <span class=\"hljs-number\">360deg<\/span>; }\n}\n<span class=\"hljs-selector-tag\">main<\/span> {\n  <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n}\n<span class=\"hljs-selector-class\">.card<\/span> {\n  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">conic-gradient<\/span>( from var(--a), red, pink, crimson, fuchsia, orange);\n  <span class=\"hljs-attribute\">animation<\/span>: cr;\n  <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_pvRRBzp\" src=\"\/\/codepen.io\/anon\/embed\/pvRRBzp?height=520&amp;theme-id=1&amp;slug-hash=pvRRBzp&amp;default-tab=result\" height=\"520\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed pvRRBzp\" title=\"CodePen Embed pvRRBzp\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s what some simple style changes look like:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_QwdvKBO\" src=\"\/\/codepen.io\/anon\/embed\/QwdvKBO?height=450&amp;theme-id=1&amp;slug-hash=QwdvKBO&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed QwdvKBO\" title=\"CodePen Embed QwdvKBO\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_azpWmjx\" src=\"\/\/codepen.io\/anon\/embed\/azpWmjx?height=450&amp;theme-id=1&amp;slug-hash=azpWmjx&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed azpWmjx\" title=\"CodePen Embed azpWmjx\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_yygbaxE\" src=\"\/\/codepen.io\/anon\/embed\/yygbaxE?height=450&amp;theme-id=1&amp;slug-hash=yygbaxE&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed yygbaxE\" title=\"CodePen Embed yygbaxE\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Boundary-aware style on draggable elements<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"draggable-box\"<\/span>&gt;<\/span>\n  Draggable box\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The <code>#draggable-box<\/code>&nbsp;element is a draggable (by JavaScript). Its position on screen, the default scroll container, changes as we drag it across the viewport. So does its color.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@keyframes<\/span> shiftColor {\n  <span class=\"hljs-selector-tag\">to<\/span> {\n    <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">203<\/span>, <span class=\"hljs-number\">49<\/span>, <span class=\"hljs-number\">242<\/span>);\n  }\n}\n<span class=\"hljs-selector-id\">#draggable-box<\/span> {\n  <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">rgb<\/span>(<span class=\"hljs-number\">41<\/span>, <span class=\"hljs-number\">113<\/span>, <span class=\"hljs-number\">248<\/span>);\n  <span class=\"hljs-attribute\">animation<\/span>: shiftColor;\n  <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">See the box\u2019s color change as you drag it from the left to the right side of the screen.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_vEggMYE\" src=\"\/\/codepen.io\/anon\/embed\/vEggMYE?height=450&amp;theme-id=1&amp;slug-hash=vEggMYE&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed vEggMYE\" title=\"CodePen Embed vEggMYE\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">You can apply the same principle in HTML sliders.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\">&lt;<span class=\"hljs-selector-tag\">input<\/span> <span class=\"hljs-selector-tag\">id<\/span>=\"<span class=\"hljs-selector-tag\">slider-range<\/span>\" <span class=\"hljs-selector-tag\">type<\/span>=\"<span class=\"hljs-selector-tag\">range<\/span>\" <span class=\"hljs-selector-tag\">min<\/span>=\"0\" <span class=\"hljs-selector-tag\">max<\/span>=\"100\" <span class=\"hljs-selector-tag\">value<\/span>=\"50\"&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@keyframes<\/span> shiftColor {\n  <span class=\"hljs-selector-tag\">from<\/span> { <span class=\"hljs-attribute\">background-color<\/span>: red; }\n  50% { <span class=\"hljs-attribute\">background-color<\/span>: yellow; }\n  <span class=\"hljs-selector-tag\">to<\/span> { <span class=\"hljs-attribute\">background-color<\/span>: green; }\n}\n<span class=\"hljs-selector-id\">#slider-range<\/span> {\n  <span class=\"hljs-comment\">\/* the slider track *\/<\/span>\n  &amp;::-webkit-slider-runnable-track{ <span class=\"hljs-comment\">\/* Webkit *\/<\/span>\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n  }\n  &amp;<span class=\"hljs-selector-pseudo\">::-moz-range-track<\/span> {             <span class=\"hljs-comment\">\/* Firefox *\/<\/span>\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n  }\n <span class=\"hljs-comment\">\/* the slider thumb *\/<\/span>\n  &amp;<span class=\"hljs-selector-pseudo\">::-webkit-slider-thumb<\/span> {         <span class=\"hljs-comment\">\/* Webkit *\/<\/span>\n    <span class=\"hljs-attribute\">animation<\/span>: shiftColor;\n    <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n  }\n  &amp;<span class=\"hljs-selector-pseudo\">::-moz-range-thumb<\/span> {             <span class=\"hljs-comment\">\/* Firefox *\/<\/span>\n    <span class=\"hljs-attribute\">animation<\/span>: shiftColor;\n    <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The slider\u2019s track is set as the scrollable container with <code>overflow: hidden<\/code>, and <code>view(x)<\/code> is applied to the thumb. There are three color stops in the <code>@keyframes<\/code> animation that <code>view()<\/code> drives. As we slide the thumb along the track from one edge to the other, its color changes between the edges and the middle.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_bNgWwmr\" src=\"\/\/codepen.io\/anon\/embed\/bNgWwmr?height=450&amp;theme-id=1&amp;slug-hash=bNgWwmr&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed bNgWwmr\" title=\"CodePen Embed bNgWwmr\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s another example where an anchor-positioned element to the thumb changes.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"slider-container\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"slider-range\"<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"range\"<\/span> <span class=\"hljs-attr\">min<\/span>=<span class=\"hljs-string\">\"0\"<\/span> <span class=\"hljs-attr\">max<\/span>=<span class=\"hljs-string\">\"100\"<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"50\"<\/span>&gt;<\/span>\n  <span class=\"hljs-comment\">&lt;!-- the anchor-positioned custom thumb --&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"slider-thumb\"<\/span>&gt;<\/span><span class=\"hljs-symbol\">&amp;#x2B50;<\/span><span class=\"hljs-symbol\">&amp;#xFE0F;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@property<\/span> --a {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">angle<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: 0<span class=\"hljs-selector-tag\">deg<\/span>;\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n}\n<span class=\"hljs-keyword\">@keyframes<\/span> shiftColor {\n  <span class=\"hljs-selector-tag\">from<\/span> { <span class=\"hljs-attribute\">--a<\/span>: <span class=\"hljs-number\">370deg<\/span> }\n  50%  { <span class=\"hljs-attribute\">--a<\/span>: <span class=\"hljs-number\">180deg<\/span> }\n  <span class=\"hljs-selector-tag\">to<\/span>   { <span class=\"hljs-attribute\">--a<\/span>: -<span class=\"hljs-number\">10deg<\/span> }\n}\n<span class=\"hljs-selector-id\">#slider-container<\/span> {\n  <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n}\n<span class=\"hljs-selector-id\">#slider-thumb<\/span> {\n  <span class=\"hljs-attribute\">background-image<\/span>: <span class=\"hljs-built_in\">conic-gradient<\/span>(crimson var(--a), dodgerblue <span class=\"hljs-built_in\">var<\/span>(--a));\n  <span class=\"hljs-attribute\">animation<\/span>: shiftColor;\n  <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>(x);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_RNKVGqa\" src=\"\/\/codepen.io\/anon\/embed\/RNKVGqa?height=450&amp;theme-id=1&amp;slug-hash=RNKVGqa&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed RNKVGqa\" title=\"CodePen Embed RNKVGqa\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">You can experiment with the axes, animation range, animation steps, and more to achieve different results. Just make sure the right ancestor is set as the scroll container using the&nbsp;<code>overflow<\/code>&nbsp;property.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You might think of the view() function as used in scroll-driven animations, but really it just pairs @keyframes animation with the current position of an element.<\/p>\n","protected":false},"author":20,"featured_media":10355,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[100,7],"class_list":["post-10341","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-animation","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/master.dev\/blog\/wp-content\/uploads\/2026\/07\/proximity.jpg?fit=2000%2C1200&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/posts\/10341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/comments?post=10341"}],"version-history":[{"count":6,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/posts\/10341\/revisions"}],"predecessor-version":[{"id":10358,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/posts\/10341\/revisions\/10358"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/media\/10355"}],"wp:attachment":[{"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/media?parent=10341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/categories?post=10341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/master.dev\/blog\/wp-json\/wp\/v2\/tags?post=10341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}