{"id":4327,"date":"2024-11-04T11:22:35","date_gmt":"2024-11-04T16:22:35","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=4327"},"modified":"2024-11-21T13:23:09","modified_gmt":"2024-11-21T18:23:09","slug":"named-scroll-view-timelines","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/named-scroll-view-timelines\/","title":{"rendered":"Named Scroll &amp; View Timelines"},"content":{"rendered":"\n<p><a href=\"https:\/\/frontendmasters.com\/blog\/scroll-driven-sections\/\">I just blogged about<\/a> a way to pass information from an element that had a view timeline on itself down to it&#8217;s descendent elements. The idea is to set up CSS custom properties with <code>@property<\/code> and the <code>@keyframe<\/code> would animate those, thus the descendent&#8217;s would have access to them.<\/p>\n\n\n\n<p>It <a href=\"https:\/\/codepen.io\/chriscoyier\/pen\/gOVXVjj\">worked fine<\/a> (noting that scroll-driven animations are, so far, only in Chrome). <\/p>\n\n\n\n<p>But Bramus <a href=\"https:\/\/frontendmasters.com\/blog\/scroll-driven-sections\/#comment-14255\">noted<\/a> that another possibility there was to <em>name<\/em> the view timeline and have the children reference that <em>instead<\/em>. His <a href=\"https:\/\/www.youtube.com\/watch?v=Dk1YA8dCgE0&amp;list=PLNYkxOF6rcICM3ttukz9x5LCNOHfWBVnn&amp;index=6&amp;t=4s\">video on this<\/a> is informative. <\/p>\n\n\n<div class=\"box article-series\">\n  <header>\n    <h3 class=\"article-series-header\">Article Series<\/h3>\n  <\/header>\n  <div class=\"box-content\">\n            <ol>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/scroll-driven-sections\/\">Scroll-Driven&#8230; Sections<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/named-scroll-view-timelines\/\">Named Scroll &amp; View Timelines<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/scoped-scroll-timelines\/\">(Up-) Scoped Scroll Timelines<\/a>\n            <\/li>\n                  <\/ol>\n        <\/div>\n<\/div>\n\n\n\n<p>The update to my original demo was pretty easy to do. Remember it had a section with a &#8220;pull quote&#8221;. The section had the view timeline, the pull quote is what I was trying to animate. So here I <em>name<\/em> the timeline (and note the scroll direction: <code>block<\/code> means vertical in logical property world):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-class\">.has-pullquote<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation<\/span>: reveal linear both;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation-timeline<\/span>: <span class=\"hljs-built_in\">view<\/span>();\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation-range<\/span>: cover <span class=\"hljs-number\">0%<\/span> cover <span class=\"hljs-number\">100%<\/span>;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">view-timeline<\/span>: --section-pullquote block;\n<\/span><\/mark><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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>You have to name the timeline with a <code>--double-sash<\/code> name like that, which in modern CSS parlance is referred to as <strong>custom ident.<em> <\/em><\/strong>It looks like a custom property but it isn&#8217;t, it&#8217;s just a unique name. <\/p>\n\n\n\n<p>Now that the timeline is named, any descendent can reference it for <em>it&#8217;s own<\/em> animation timeline. Again specific to my demo, I switched things up to work like this (just the basics):<\/p>\n\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 shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">blockquote<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/* Pull quote styling... *\/<\/span> \n<\/span><\/span><span class='shcb-loc'><span>  \n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation<\/span>: blockquote linear both;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation-timeline<\/span>: --section-pullquote;\n<\/span><\/mark><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">@keyframes<\/span> blockquote {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-selector-tag\">from<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">opacity<\/span>: <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-selector-tag\">to<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">opacity<\/span>: <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/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><a href=\"https:\/\/codepen.io\/chriscoyier\/pen\/GRVdWwr?editors=0100\">Here&#8217;s an updated demo<\/a> using that technique instead of animating all custom properties.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_GRVdWwr\" src=\"\/\/codepen.io\/anon\/embed\/GRVdWwr?height=650&amp;theme-id=47434&amp;slug-hash=GRVdWwr&amp;default-tab=result\" height=\"650\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed GRVdWwr\" title=\"CodePen Embed GRVdWwr\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>The actual demo updates a few more things just to have a bit more of a play and try things out. Notably, <em>one<\/em> of the effects still required me to animate a custom property still. That&#8217;s because I&#8217;m animating the color-stop of a gradient, and since that&#8217;s just <em>a part<\/em> of a whole valid value, it really needs to be done as a custom property. <\/p>\n\n\n\n<p>Still, <em>most<\/em> of the animation work was moved over to using a keyframe applied directly to the descendent element itself, which I think is a logical improvement and I think it&#8217;s very cool how you can do that. <\/p>\n\n\n\n<p class=\"learn-more\">Essentially: you can name a view (or scroll) animation timeline (<code>view-timeline<\/code> or <code>scroll-timeline<\/code>) and any descendent element can tap into it and base it&#8217;s animation off of that (<code>animation-timeline<\/code>). <\/p>\n\n\n\n<p>The fact that it works for descendents only is interesting to me. When I was playing with this to try to understand it, my first thought was to try to make a random element on the page have a <code>scroll-timeline<\/code> and another totally random element on the page &#8220;listen&#8221; to that one for it&#8217;s <code>animation-timeline<\/code>. I made them <em>siblings<\/em> and was confused why it wasn&#8217;t working. That ain&#8217;t gonna work, apparently, gotta have that parent\/child thing going on. (Bramus&#8217; <a href=\"https:\/\/www.youtube.com\/watch?v=Dk1YA8dCgE0&amp;list=PLNYkxOF6rcICM3ttukz9x5LCNOHfWBVnn&amp;index=6&amp;t=4s\">video<\/a> notes another gotcha: intermediary parents with <code>overflow: hidden<\/code> ruining the effect, and a perfect solution: <code>overflow: clip<\/code>). <\/p>\n\n\n\n<p>I updated my playing to make it a parent\/child relationship, and here&#8217;s that silly idea:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_JjgvNgJ\" src=\"\/\/codepen.io\/anon\/embed\/JjgvNgJ?height=550&amp;theme-id=47434&amp;slug-hash=JjgvNgJ&amp;default-tab=css,result\" height=\"550\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed JjgvNgJ\" title=\"CodePen Embed JjgvNgJ\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>There you can see the &#8220;number&#8221; using the &#8220;scroller&#8221;s <code>scroll-timeline<\/code> for it&#8217;s <code>animation-timeline<\/code> and &#8220;animating&#8221; an integer value. If I wanted to take that integer and place it <em>wherever<\/em> on the page, it&#8217;s somewhat limiting because the parent container necessarily has <code>overflow<\/code> on it so it scrolls. <\/p>\n\n\n\n<p>It does make me wonder if anchor positioning or even some abuse of <code>popover<\/code> would be able to pop it out of that constrained container, but that&#8217;ll have to be an exploration for another day. <\/p>\n\n\n<div class=\"box article-series\">\n  <header>\n    <h3 class=\"article-series-header\">Article Series<\/h3>\n  <\/header>\n  <div class=\"box-content\">\n            <ol>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/scroll-driven-sections\/\">Scroll-Driven&#8230; Sections<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/named-scroll-view-timelines\/\">Named Scroll &amp; View Timelines<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/scoped-scroll-timelines\/\">(Up-) Scoped Scroll Timelines<\/a>\n            <\/li>\n                  <\/ol>\n        <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>If you give a scroll or view timeline a &#8211;custom-ident name, then any descendent can &#8220;listen&#8221; to that timeline and base @keyframe animations off of it.<\/p>\n","protected":false},"author":1,"featured_media":4335,"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_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[7,57],"class_list":["post-4327","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-css","tag-scroll-driven-animations"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/11\/scroller.jpg?fit=1000%2C531&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/4327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=4327"}],"version-history":[{"count":9,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/4327\/revisions"}],"predecessor-version":[{"id":4575,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/4327\/revisions\/4575"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/4335"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=4327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=4327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=4327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}