[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-config":3,"course-tree":6,"blog-categories":646,"topic:css-scroll-driven-animations":670},{"data":4},{"google_site_verification":5,"ga4_measurement_id":5,"site_name":5,"default_og_image":5,"twitter_handle":5},null,{"data":7},[8,334],{"id":9,"name":10,"slug":11,"icon":5,"icon_url":5,"short_description":12,"meta_title":13,"meta_description":14,"og_image":15,"locale":16,"subcategories":17},1,"HTML","html-tutorial","Welcome to our HTML Tutorial for Beginners, a complete guide designed to help you learn HTML from the ground up.\n\nHTML, which stands for HyperText Markup Language, is the standard language used to structure content on the web. Whether you want to become a web developer, build your own website, or continue learning CSS and JavaScript, understanding HTML is an essential first step.\n\nThis HTML course takes you through the fundamentals step by step, using simple explanations and practical examples. ","HTML Tutorial for Beginners - Learn HTML Step by Step","Learn HTML from scratch with our beginner-friendly HTML tutorial. Understand HTML tags, elements, forms, tables, links, images, semantic HTML and more with practical examples.","https:\u002F\u002Fwpfsharp.com\u002Fstorage\u002Fcourses\u002Fog\u002F01M2GK0XN45C0B937NF9XFAD4S.webp","en",[18,46,82,106,182,216,230,258,282,298],{"id":9,"name":19,"slug":20,"order_index":9,"topics":21},"HTML Fundamentals & Setup","html-fundamentals-setup",[22,27,30,34,38,42],{"id":23,"title":24,"slug":25,"order_index":9,"cornerstone":26,"reading_time_minutes":23},2,"HTML Editors & Environment Setup","html-editors-and-environment-setup",false,{"id":9,"title":28,"slug":29,"order_index":9,"cornerstone":26,"reading_time_minutes":9},"HTML Introduction & History","html-introduction-and-history",{"id":31,"title":32,"slug":33,"order_index":31,"cornerstone":26,"reading_time_minutes":23},3,"HTML Basic Syntax & Document Structure","html-basic-syntax-document-structure",{"id":35,"title":36,"slug":37,"order_index":35,"cornerstone":26,"reading_time_minutes":23},4,"HTML Elements & Tags Explained","html-elements-tags-explained",{"id":39,"title":40,"slug":41,"order_index":39,"cornerstone":26,"reading_time_minutes":23},5,"HTML Attributes (Global & Standard)","html-attributes-global-standard",{"id":43,"title":44,"slug":45,"order_index":43,"cornerstone":26,"reading_time_minutes":23},6,"Understanding the DOCTYPE & HTML5 Boilerplate","understanding-doctype-html5-boilerplate",{"id":23,"name":47,"slug":48,"order_index":23,"topics":49},"Text & Content Basics","text-content-basics",[50,54,58,62,66,70,74,78],{"id":51,"title":52,"slug":53,"order_index":51,"cornerstone":26,"reading_time_minutes":23},7,"HTML Headings (H1–H6) & SEO Best Practices","html-headings-h1-h6-seo-best-practices",{"id":55,"title":56,"slug":57,"order_index":55,"cornerstone":26,"reading_time_minutes":23},8,"HTML Paragraphs & Line Breaks","html-paragraphs-line-breaks",{"id":59,"title":60,"slug":61,"order_index":59,"cornerstone":26,"reading_time_minutes":9},9,"HTML Text Formatting (Bold, Italic, Mark, etc.)","html-text-formatting-bold-italic-mark",{"id":63,"title":64,"slug":65,"order_index":63,"cornerstone":26,"reading_time_minutes":23},10,"HTML Styles (Inline CSS Basics)","html-styles-inline-css-basics",{"id":67,"title":68,"slug":69,"order_index":67,"cornerstone":26,"reading_time_minutes":23},11,"HTML Quotations & Citations (blockquote, q, cite)","html-quotations-citations-blockquote-q-cite",{"id":71,"title":72,"slug":73,"order_index":71,"cornerstone":26,"reading_time_minutes":23},12,"HTML Comments (Best Practices)","html-comments-best-practices",{"id":75,"title":76,"slug":77,"order_index":75,"cornerstone":26,"reading_time_minutes":23},13,"HTML Colors (Names, HEX, RGB, HSL)","html-colors-names-hex-rgb-hsl",{"id":79,"title":80,"slug":81,"order_index":79,"cornerstone":26,"reading_time_minutes":23},14,"HTML & CSS Integration (Inline, Internal, External)","html-css-integration-inline-internal-external",{"id":31,"name":83,"slug":84,"order_index":31,"topics":85},"Links, Media & Navigation","links-media-navigation",[86,90,94,98,102],{"id":87,"title":88,"slug":89,"order_index":87,"cornerstone":26,"reading_time_minutes":23},15,"HTML Links (Anchor Tags & Hyperlinks)","html-links-anchor-tags-hyperlinks",{"id":91,"title":92,"slug":93,"order_index":91,"cornerstone":26,"reading_time_minutes":23},16,"HTML Images (Alt Text, Lazy Loading, Formats)","html-images-alt-text-lazy-loading-formats",{"id":95,"title":96,"slug":97,"order_index":95,"cornerstone":26,"reading_time_minutes":9},17,"HTML Favicon Setup","html-favicon-setup",{"id":99,"title":100,"slug":101,"order_index":99,"cornerstone":26,"reading_time_minutes":23},18,"HTML Page Title & Meta Tags (SEO Essentials)","html-page-title-meta-tags-seo-essentials",{"id":103,"title":104,"slug":105,"order_index":103,"cornerstone":26,"reading_time_minutes":23},19,"HTML File Paths (Absolute vs Relative)","html-file-paths-absolute-vs-relative",{"id":35,"name":107,"slug":108,"order_index":35,"topics":109},"Structuring Content","structuring-content",[110,115,120,125,130,134,138,142,146,150,154,158,162,166,170,174,178],{"id":111,"title":112,"slug":113,"order_index":114,"cornerstone":26,"reading_time_minutes":23},24,"HTML Tables Explained: Rows, Columns & Merging Cells","html-tables-rows-columns-merging-cells",20,{"id":116,"title":117,"slug":118,"order_index":119,"cornerstone":26,"reading_time_minutes":23},25,"HTML Lists: Ordered, Unordered & Description Lists","html-lists-ordered-unordered-description",21,{"id":121,"title":122,"slug":123,"order_index":124,"cornerstone":26,"reading_time_minutes":23},26,"HTML Block vs Inline Elements Explained","html-block-vs-inline-elements",22,{"id":126,"title":127,"slug":128,"order_index":129,"cornerstone":26,"reading_time_minutes":9},27,"HTML Div & Span: Generic Containers Explained","html-div-and-span-containers",23,{"id":131,"title":132,"slug":133,"order_index":111,"cornerstone":26,"reading_time_minutes":23},28,"HTML Classes vs ID: Selectors Explained","html-classes-vs-id-selectors-explained",{"id":135,"title":136,"slug":137,"order_index":116,"cornerstone":26,"reading_time_minutes":9},29,"HTML Iframes: Embedding External Content","html-iframes-embedding-content",{"id":139,"title":140,"slug":141,"order_index":121,"cornerstone":26,"reading_time_minutes":23},30,"HTML Head Element Deep Dive","html-head-element-deep-dive",{"id":143,"title":144,"slug":145,"order_index":126,"cornerstone":26,"reading_time_minutes":23},31,"HTML Layout Techniques: Header, Nav & Footer","html-layout-techniques-header-nav-footer",{"id":147,"title":148,"slug":149,"order_index":131,"cornerstone":26,"reading_time_minutes":23},32,"Responsive HTML Design: Mobile-First Approach","responsive-html-design-mobile-first-approach",{"id":151,"title":152,"slug":153,"order_index":135,"cornerstone":26,"reading_time_minutes":31},74,"HTML Semantic Elements (article, section, aside, nav)","html-semantic-elements-article-section-aside-nav",{"id":155,"title":156,"slug":157,"order_index":139,"cornerstone":26,"reading_time_minutes":23},75,"HTML Style Guide & Coding Conventions","html-style-guide-coding-conventions",{"id":159,"title":160,"slug":161,"order_index":143,"cornerstone":26,"reading_time_minutes":23},76,"HTML Entities & Special Characters","html-entities-special-characters",{"id":163,"title":164,"slug":165,"order_index":147,"cornerstone":26,"reading_time_minutes":9},77,"HTML Symbols","html-symbols",{"id":167,"title":168,"slug":169,"order_index":167,"cornerstone":26,"reading_time_minutes":9},33,"HTML Emojis 😀: How to Use Them in Web Pages","html-emojis-trending-guide",{"id":171,"title":172,"slug":173,"order_index":171,"cornerstone":26,"reading_time_minutes":23},34,"HTML Character Sets: UTF-8 & Encoding Explained","html-character-sets-utf-8-encoding",{"id":175,"title":176,"slug":177,"order_index":175,"cornerstone":26,"reading_time_minutes":9},35,"HTML URL Encoding Explained","html-url-encoding-explained",{"id":179,"title":180,"slug":181,"order_index":179,"cornerstone":26,"reading_time_minutes":9},36,"HTML vs XHTML: Key Differences","html-vs-xhtml-key-differences",{"id":51,"name":183,"slug":184,"order_index":39,"topics":185},"Forms & User Input","forms-user-input",[186,191,196,201,206,211],{"id":187,"title":188,"slug":189,"order_index":190,"cornerstone":26,"reading_time_minutes":23},49,"HTML Forms Introduction","html-forms-introduction",37,{"id":192,"title":193,"slug":194,"order_index":195,"cornerstone":26,"reading_time_minutes":9},50,"HTML Form Attributes (action, method, etc.)","html-form-attributes-action-method",38,{"id":197,"title":198,"slug":199,"order_index":200,"cornerstone":26,"reading_time_minutes":9},51,"HTML Form Elements (input, select, textarea, button)","html-form-elements-input-select-textarea-button",39,{"id":202,"title":203,"slug":204,"order_index":205,"cornerstone":26,"reading_time_minutes":23},52,"HTML Input Types (Modern Types: email, date, color, range)","html-input-types-modern-email-date-color-range",40,{"id":207,"title":208,"slug":209,"order_index":210,"cornerstone":26,"reading_time_minutes":23},53,"HTML Input Attributes (required, placeholder, pattern)","html-input-attributes-required-placeholder-pattern",41,{"id":212,"title":213,"slug":214,"order_index":215,"cornerstone":26,"reading_time_minutes":23},54,"HTML Form Validation (Client-Side)","html-form-validation-client-side",42,{"id":55,"name":217,"slug":218,"order_index":43,"topics":219},"Graphics & Visuals","graphics-visuals",[220,225],{"id":221,"title":222,"slug":223,"order_index":224,"cornerstone":26,"reading_time_minutes":31},55,"HTML Canvas (2D Drawing API) 🔥","html-canvas-2d-drawing-api",43,{"id":226,"title":227,"slug":228,"order_index":229,"cornerstone":26,"reading_time_minutes":31},56,"HTML SVG (Scalable Vector Graphics)","html-svg-scalable-vector-graphics",44,{"id":59,"name":231,"slug":232,"order_index":51,"topics":233},"Multimedia","multimedia",[234,239,244,249,254],{"id":235,"title":236,"slug":237,"order_index":238,"cornerstone":26,"reading_time_minutes":23},57,"HTML Media Overview","html-media-overview",45,{"id":240,"title":241,"slug":242,"order_index":243,"cornerstone":26,"reading_time_minutes":23},58,"HTML Video Embedding (Native Player)","html-video-embedding-native-player",46,{"id":245,"title":246,"slug":247,"order_index":248,"cornerstone":26,"reading_time_minutes":23},59,"HTML Audio Embedding","html-audio-embedding",47,{"id":250,"title":251,"slug":252,"order_index":253,"cornerstone":26,"reading_time_minutes":23},60,"HTML Plug-ins (Object & Embed Tags)","html-plugins-object-embed-tags",48,{"id":255,"title":256,"slug":257,"order_index":187,"cornerstone":26,"reading_time_minutes":23},61,"Embedding YouTube Videos in HTML","embedding-youtube-videos-in-html",{"id":63,"name":259,"slug":260,"order_index":55,"topics":261},"HTML5 Web APIs (Advanced\u002FTrending)","html5-web-apis-advancedtrending",[262,266,270,274,278],{"id":263,"title":264,"slug":265,"order_index":192,"cornerstone":26,"reading_time_minutes":23},62,"HTML Geolocation API","html-geolocation-api",{"id":267,"title":268,"slug":269,"order_index":197,"cornerstone":26,"reading_time_minutes":23},63,"HTML Drag & Drop API","html-drag-and-drop-api",{"id":271,"title":272,"slug":273,"order_index":202,"cornerstone":26,"reading_time_minutes":23},64,"HTML Web Storage (localStorage & sessionStorage)","html-web-storage-localstorage-sessionstorage",{"id":275,"title":276,"slug":277,"order_index":207,"cornerstone":26,"reading_time_minutes":23},65,"HTML Web Workers (Background Processing)","html-web-workers-background-processing",{"id":279,"title":280,"slug":281,"order_index":212,"cornerstone":26,"reading_time_minutes":23},66,"HTML Server-Sent Events (SSE)","html-server-sent-events-sse",{"id":67,"name":283,"slug":284,"order_index":59,"topics":285},"Accessibility & Best Practices (High-Demand  Skill) �","accessibility-best-practices-high-demand-skill",[286,290,294],{"id":287,"title":288,"slug":289,"order_index":221,"cornerstone":26,"reading_time_minutes":23},67,"HTML Accessibility (ARIA, Screen Readers)","html-accessibility-aria-screen-readers",{"id":291,"title":292,"slug":293,"order_index":226,"cornerstone":26,"reading_time_minutes":23},68,"Writing Semantic & SEO-Friendly HTML","writing-semantic-and-seo-friendly-html",{"id":295,"title":296,"slug":297,"order_index":235,"cornerstone":26,"reading_time_minutes":23},69,"HTML Performance Optimization Basics","html-performance-optimization-basics",{"id":71,"name":299,"slug":300,"order_index":63,"topics":301},"Reference & Practice","reference-practice",[302,306,310,314,318,322,326,330],{"id":303,"title":304,"slug":305,"order_index":9,"cornerstone":26,"reading_time_minutes":23},70,"HTML Tag List (Full Reference)","html-tag-list-full-reference",{"id":307,"title":308,"slug":309,"order_index":23,"cornerstone":26,"reading_time_minutes":23},71,"HTML Global Attributes Reference","html-global-attributes-reference",{"id":311,"title":312,"slug":313,"order_index":31,"cornerstone":26,"reading_time_minutes":23},72,"HTML Events Reference","html-events-reference",{"id":315,"title":316,"slug":317,"order_index":35,"cornerstone":26,"reading_time_minutes":23},73,"HTML Browser Support & Compatibility","html-browser-support-compatibility",{"id":319,"title":320,"slug":321,"order_index":39,"cornerstone":26,"reading_time_minutes":23},78,"HTML Doctypes Reference","html-doctypes-reference",{"id":323,"title":324,"slug":325,"order_index":43,"cornerstone":26,"reading_time_minutes":23},79,"HTTP Methods & Messages (Basics for Forms\u002FAPIs)","http-methods-messages-basics",{"id":327,"title":328,"slug":329,"order_index":51,"cornerstone":26,"reading_time_minutes":31},80,"HTML Interview Preparation (Top Q&A)","html-interview-preparation-top-qa",{"id":331,"title":332,"slug":333,"order_index":55,"cornerstone":26,"reading_time_minutes":9},81,"HTML Quiz & Practice Exercises","html-quiz-practice-exercises",{"id":23,"name":335,"slug":336,"icon":5,"icon_url":5,"short_description":337,"meta_title":338,"meta_description":339,"og_image":5,"locale":16,"subcategories":340},"CSS","css","Master CSS from basics to advanced. Learn styling, layouts, Flexbox, Grid, and responsive design with practical examples.","CSS Course - Learn CSS from Scratch to Advanced","Learn CSS (Cascading Style Sheets) step by step. Master selectors, layouts, Flexbox, Grid, animations, and responsive web design with hands-on examples.",[341,370,394,430,462,494,526,558,586,614],{"id":129,"name":342,"slug":343,"order_index":344,"topics":345},"UI Components","ui-components",0,[346,350,354,358,362,366],{"id":347,"title":348,"slug":349,"order_index":255,"cornerstone":26,"reading_time_minutes":43},148,"CSS Buttons: Variants, States, Sizes and Accessible Button Design","css-buttons",{"id":351,"title":352,"slug":353,"order_index":263,"cornerstone":26,"reading_time_minutes":43},149,"CSS Card Component: Layouts with Flexbox, Grid, Container Queries and Subgrid","css-cards",{"id":355,"title":356,"slug":357,"order_index":267,"cornerstone":26,"reading_time_minutes":51},150,"CSS Navbar and Dropdown Menus: Responsive, Sticky and Accessible Navigation","css-navbar-dropdowns",{"id":359,"title":360,"slug":361,"order_index":271,"cornerstone":26,"reading_time_minutes":43},151,"HTML and CSS Forms and Inputs: Styled, Accessible and Validated Form Controls","css-forms-inputs",{"id":363,"title":364,"slug":365,"order_index":275,"cornerstone":26,"reading_time_minutes":43},152,"CSS Tooltips and Popovers: Popover API, Anchor Positioning and Accessible Overlays","css-tooltips-popovers",{"id":367,"title":368,"slug":369,"order_index":279,"cornerstone":26,"reading_time_minutes":43},153,"Pagination and Breadcrumbs: Accessible Navigation Patterns with HTML, CSS and Schema","pagination-breadcrumbs",{"id":75,"name":371,"slug":372,"order_index":344,"topics":373},"CSS Fundamentals & Setup","css-fundamentals-setup",[374,378,382,386,390],{"id":375,"title":376,"slug":377,"order_index":9,"cornerstone":26,"reading_time_minutes":35},82,"CSS Introduction & History: What Is CSS and Why It Matters","css-introduction-and-history",{"id":379,"title":380,"slug":381,"order_index":23,"cornerstone":26,"reading_time_minutes":35},83,"CSS Syntax & How Browsers Apply Styles","css-syntax-how-browsers-apply-styles",{"id":383,"title":384,"slug":385,"order_index":31,"cornerstone":26,"reading_time_minutes":31},84,"Setting Up Your CSS Workspace: Linking Files & Live Server","setting-up-css-workspace-linking-files-live-server",{"id":387,"title":388,"slug":389,"order_index":35,"cornerstone":26,"reading_time_minutes":31},85,"CSS Comments & Code Formatting Best Practices","css-comments-and-code-formatting",{"id":391,"title":392,"slug":393,"order_index":39,"cornerstone":26,"reading_time_minutes":39},86,"Browser DevTools for CSS: Inspect, Debug & Edit Styles Live","browser-devtools-for-css",{"id":79,"name":395,"slug":396,"order_index":344,"topics":397},"Selectors & the Cascade","selectors-the-cascade",[398,402,406,410,414,418,422,426],{"id":399,"title":400,"slug":401,"order_index":43,"cornerstone":26,"reading_time_minutes":35},87,"CSS Basic Selectors: Type, Class, ID, Universal & Grouping","css-basic-selectors",{"id":403,"title":404,"slug":405,"order_index":51,"cornerstone":26,"reading_time_minutes":35},88,"CSS Combinators: Descendant, Child, Adjacent & General Sibling","css-combinators",{"id":407,"title":408,"slug":409,"order_index":55,"cornerstone":26,"reading_time_minutes":35},89,"CSS Attribute Selectors: [attr], ^=, $=, *= and More","css-attribute-selectors",{"id":411,"title":412,"slug":413,"order_index":59,"cornerstone":26,"reading_time_minutes":43},90,"CSS Pseudo-classes: :hover, :focus, :nth-child & Modern Selectors","css-pseudo-classes",{"id":415,"title":416,"slug":417,"order_index":63,"cornerstone":26,"reading_time_minutes":39},91,"CSS Pseudo-elements (::before, ::after)","css-pseudo-elements-before-after",{"id":419,"title":420,"slug":421,"order_index":67,"cornerstone":26,"reading_time_minutes":39},92,"Modern CSS Selectors: :is(), :where(), :has()","modern-css-selectors-is-where-has",{"id":423,"title":424,"slug":425,"order_index":71,"cornerstone":26,"reading_time_minutes":35},93,"CSS Specificity Explained","css-specificity-explained",{"id":427,"title":428,"slug":429,"order_index":75,"cornerstone":26,"reading_time_minutes":39},94,"Cascade, Inheritance & !important","css-cascade-inheritance-important",{"id":87,"name":431,"slug":432,"order_index":344,"topics":433},"Colors, Backgrounds & Effects","colors-backgrounds-effects",[434,438,442,446,450,454,458],{"id":435,"title":436,"slug":437,"order_index":79,"cornerstone":26,"reading_time_minutes":39},95,"CSS Colors (HEX, RGB, HSL, OKLCH)","css-colors-hex-rgb-hsl-oklch",{"id":439,"title":440,"slug":441,"order_index":87,"cornerstone":26,"reading_time_minutes":35},96,"CSS Backgrounds","css-backgrounds",{"id":443,"title":444,"slug":445,"order_index":91,"cornerstone":26,"reading_time_minutes":39},97,"CSS Gradients (Linear, Radial, Conic)","css-gradients-linear-radial-conic",{"id":447,"title":448,"slug":449,"order_index":95,"cornerstone":26,"reading_time_minutes":39},98,"CSS Borders, Outlines & Rounded Corners","css-borders-outlines-rounded-corners",{"id":451,"title":452,"slug":453,"order_index":99,"cornerstone":26,"reading_time_minutes":43},99,"CSS Box Shadow & Text Shadow","css-box-shadow-text-shadow",{"id":455,"title":456,"slug":457,"order_index":103,"cornerstone":26,"reading_time_minutes":39},100,"CSS Opacity & Blend Modes","css-opacity-blend-modes",{"id":459,"title":460,"slug":461,"order_index":114,"cornerstone":26,"reading_time_minutes":43},101,"CSS Filters & backdrop-filter (Glassmorphism)","css-filters-backdrop-filter-glassmorphism",{"id":91,"name":463,"slug":464,"order_index":344,"topics":465},"Box Model & Spacing","box-model-spacing",[466,470,474,478,482,486,490],{"id":467,"title":468,"slug":469,"order_index":119,"cornerstone":26,"reading_time_minutes":51},102,"The CSS Box Model: Content, Padding, Border and Margin","css-box-model",{"id":471,"title":472,"slug":473,"order_index":124,"cornerstone":26,"reading_time_minutes":51},103,"CSS Margin and Margin Collapse","css-margin-and-margin-collapse",{"id":475,"title":476,"slug":477,"order_index":129,"cornerstone":26,"reading_time_minutes":43},104,"CSS Padding: Shorthand, Percentages and Best Practices","css-padding",{"id":479,"title":480,"slug":481,"order_index":111,"cornerstone":26,"reading_time_minutes":59},105,"CSS Width, Height, Min-Width, Max-Width, Min-Height & Max-Height","css-width-height-min-max",{"id":483,"title":484,"slug":485,"order_index":116,"cornerstone":26,"reading_time_minutes":39},106,"CSS box-sizing: content-box vs border-box","css-box-sizing",{"id":487,"title":488,"slug":489,"order_index":121,"cornerstone":26,"reading_time_minutes":51},107,"CSS Overflow: hidden, scroll, auto, clip and Text Truncation","css-overflow",{"id":491,"title":492,"slug":493,"order_index":126,"cornerstone":26,"reading_time_minutes":51},108,"CSS Units: px, rem, em, %, vw, vh and dvh","css-units",{"id":95,"name":495,"slug":496,"order_index":344,"topics":497},"Typography & Text","typography-text",[498,502,506,510,514,518,522],{"id":499,"title":500,"slug":501,"order_index":131,"cornerstone":26,"reading_time_minutes":51},109,"CSS Text Properties: Alignment, Spacing, Decoration and Wrapping","css-text-properties",{"id":503,"title":504,"slug":505,"order_index":135,"cornerstone":26,"reading_time_minutes":51},110,"CSS Fonts and font-family: Font Stacks, Weights and System Fonts","css-fonts-font-family",{"id":507,"title":508,"slug":509,"order_index":139,"cornerstone":26,"reading_time_minutes":51},111,"Web Fonts: Google Fonts, @font-face and Variable Fonts","web-fonts",{"id":511,"title":512,"slug":513,"order_index":143,"cornerstone":26,"reading_time_minutes":51},112,"CSS Text Effects: text-wrap balance, line-clamp, Ellipsis and More","css-text-effects",{"id":515,"title":516,"slug":517,"order_index":147,"cornerstone":26,"reading_time_minutes":55},113,"Styling Links","styling-links-css",{"id":519,"title":520,"slug":521,"order_index":167,"cornerstone":26,"reading_time_minutes":51},114,"Styling Lists & Tables","styling-lists-and-tables-css",{"id":523,"title":524,"slug":525,"order_index":171,"cornerstone":26,"reading_time_minutes":63},115,"Icons (SVG & Icon Fonts)","icons-svg-and-icon-fonts",{"id":99,"name":527,"slug":528,"order_index":344,"topics":529},"Display, Position & Layout Basics","display-position-layout-basics",[530,534,538,542,546,550,554],{"id":531,"title":532,"slug":533,"order_index":175,"cornerstone":26,"reading_time_minutes":51},116,"Display & Inline-block","display-and-inline-block",{"id":535,"title":536,"slug":537,"order_index":179,"cornerstone":26,"reading_time_minutes":43},117,"Position (relative, absolute, fixed, sticky)","position-relative-absolute-fixed-sticky",{"id":539,"title":540,"slug":541,"order_index":190,"cornerstone":26,"reading_time_minutes":43},118,"Z-index & Stacking Contexts","z-index-and-stacking-contexts",{"id":543,"title":544,"slug":545,"order_index":195,"cornerstone":26,"reading_time_minutes":39},119,"Float & Clear (Legacy, and Why to Avoid It)","float-and-clear",{"id":547,"title":548,"slug":549,"order_index":200,"cornerstone":26,"reading_time_minutes":43},120,"Centering Techniques","centering-techniques",{"id":551,"title":552,"slug":553,"order_index":205,"cornerstone":26,"reading_time_minutes":51},121,"aspect-ratio & object-fit","aspect-ratio-and-object-fit",{"id":555,"title":556,"slug":557,"order_index":210,"cornerstone":26,"reading_time_minutes":55},122,"Website Layout Basics","website-layout-basics",{"id":114,"name":559,"slug":560,"order_index":344,"topics":561},"The Modern CSS Toolkit","the-modern-css-toolkit",[562,566,570,574,578,582],{"id":563,"title":564,"slug":565,"order_index":215,"cornerstone":26,"reading_time_minutes":55},129,"CSS Variables (Custom Properties)","css-variables-custom-properties",{"id":567,"title":568,"slug":569,"order_index":224,"cornerstone":26,"reading_time_minutes":55},130,"Math Functions (calc, min, max, clamp)","math-functions-calc-min-max-clamp",{"id":571,"title":572,"slug":573,"order_index":229,"cornerstone":26,"reading_time_minutes":51},131,"Native CSS Nesting","native-css-nesting",{"id":575,"title":576,"slug":577,"order_index":238,"cornerstone":26,"reading_time_minutes":51},132,"Cascade Layers (@layer)","cascade-layers-at-layer",{"id":579,"title":580,"slug":581,"order_index":243,"cornerstone":26,"reading_time_minutes":59},133,"Dark Mode (prefers-color-scheme, light-dark())","dark-mode-prefers-color-scheme-light-dark",{"id":583,"title":584,"slug":585,"order_index":248,"cornerstone":26,"reading_time_minutes":55},134,"CSS Reset & Normalize","css-reset-and-normalize",{"id":119,"name":587,"slug":588,"order_index":344,"topics":589},"Responsive Design","responsive-design",[590,594,598,602,606,610],{"id":591,"title":592,"slug":593,"order_index":253,"cornerstone":26,"reading_time_minutes":59},135,"Mobile-First & the Viewport","mobile-first-and-the-viewport",{"id":595,"title":596,"slug":597,"order_index":187,"cornerstone":26,"reading_time_minutes":55},136,"Media Queries","media-queries",{"id":599,"title":600,"slug":601,"order_index":192,"cornerstone":26,"reading_time_minutes":55},137,"Responsive Images & Video","responsive-images-and-video",{"id":603,"title":604,"slug":605,"order_index":197,"cornerstone":26,"reading_time_minutes":59},138,"Fluid Typography with clamp()","fluid-typography-with-clamp",{"id":607,"title":608,"slug":609,"order_index":202,"cornerstone":26,"reading_time_minutes":59},139,"Container Queries","container-queries",{"id":611,"title":612,"slug":613,"order_index":207,"cornerstone":26,"reading_time_minutes":71},140,"Responsive Navigation Pattern","responsive-navigation-pattern",{"id":124,"name":615,"slug":616,"order_index":344,"topics":617},"Transitions & Animation","transitions-animation",[618,622,626,630,634,638,642],{"id":619,"title":620,"slug":621,"order_index":212,"cornerstone":26,"reading_time_minutes":39},141,"CSS Transitions: Smooth State Changes with transition, @starting-style and allow-discrete","css-transitions",{"id":623,"title":624,"slug":625,"order_index":221,"cornerstone":26,"reading_time_minutes":35},142,"CSS 2D Transforms: translate, rotate, scale, skew and transform-origin","css-2d-transforms",{"id":627,"title":628,"slug":629,"order_index":226,"cornerstone":26,"reading_time_minutes":39},143,"CSS 3D Transforms: perspective, preserve-3d, rotateX\u002FY and backface-visibility","css-3d-transforms",{"id":631,"title":632,"slug":633,"order_index":235,"cornerstone":26,"reading_time_minutes":39},144,"CSS Keyframe Animations: @keyframes, animation shorthand, fill-mode and @property","css-keyframe-animations",{"id":635,"title":636,"slug":637,"order_index":240,"cornerstone":26,"reading_time_minutes":39},145,"CSS Scroll-Driven Animations: animation-timeline, scroll() and view()","css-scroll-driven-animations",{"id":639,"title":640,"slug":641,"order_index":245,"cornerstone":26,"reading_time_minutes":39},146,"CSS View Transitions API: Progressive Enhancement for Page and State Animations","css-view-transitions",{"id":643,"title":644,"slug":645,"order_index":250,"cornerstone":26,"reading_time_minutes":43},147,"Motion Accessibility and Performance: prefers-reduced-motion, will-change and Smooth 60fps Animations","motion-accessibility-prefers-reduced-motion-performance",{"data":647},[648,651,655,660,665],{"name":335,"slug":336,"description":649,"post_count":23,"subcategories":650},"Learn CSS with practical tutorials and examples covering layouts, Flexbox, Grid, responsive design, typography, positioning, animations, and more.",[],{"name":10,"slug":652,"description":653,"post_count":23,"subcategories":654},"html","Learn HTML with practical tutorials and examples for beginners. Explore HTML tags, elements, attributes, links, images, forms, semantic HTML, and more with clear explanations and real code examples.",[],{"name":656,"slug":657,"description":658,"post_count":9,"subcategories":659},"WPF","wpf","Learn WPF with practical tutorials and examples covering XAML, windows, controls, layouts, data binding, MVVM, commands, styles, templates, debugging, and modern WPF UI development.",[],{"name":661,"slug":662,"description":663,"post_count":9,"subcategories":664},"Python","python","Learn Python with practical tutorials covering strings, lists, functions, exceptions, files, packages, virtual environments, modules, classes, and beginner programming concepts.",[],{"name":666,"slug":667,"description":668,"post_count":9,"subcategories":669},"Java","java","Learn Java with practical tutorials and examples for beginners. Explore Java syntax, variables, data types, classes, objects, methods, inheritance, exceptions, collections, and more with clear explanations and real code examples.",[],{"data":671},{"id":635,"title":636,"slug":637,"content":672,"course":673,"subcategory":674,"author":675,"reading_time_minutes":39,"cornerstone":26,"schema_type":681,"faq_json":5,"video_url":5,"canonical_url":682,"meta_title":683,"meta_description":684,"og_image":5,"toc_json":685,"code_examples":718,"quiz":5,"exercises":732,"published_at":5,"updated_at":740,"prev":741,"next":742},"\u003Ch2 id=\"what-are-scroll-driven-animations\">What are scroll-driven animations?\u003C\u002Fh2>\u003Cp>\u003Cstrong>CSS scroll-driven animations\u003C\u002Fstrong> link the progress of an animation to scrolling instead of time. Scroll down and the animation plays forward; scroll up and it plays backward. You get reading progress bars, reveal-on-scroll effects, parallax and sticky header changes using only CSS, with no \u003Ccode>scroll\u003C\u002Fcode> event listeners or IntersectionObserver. Because they can run off the main thread in supporting browsers, they are often smoother than JavaScript solutions.\u003C\u002Fp>\u003Cp>Focus keyword: \u003Cstrong>CSS scroll-driven animations\u003C\u002Fstrong>. Related trending keywords: \u003Cem>animation-timeline\u003C\u002Fem>, \u003Cem>scroll progress bar CSS\u003C\u002Fem>, \u003Cem>view() timeline\u003C\u002Fem>, \u003Cem>animation-range\u003C\u002Fem>, \u003Cem>scroll reveal animation without JavaScript\u003C\u002Fem>, \u003Cem>CSS parallax\u003C\u002Fem>, \u003Cem>scroll-timeline\u003C\u002Fem>, \u003Cem>view-timeline\u003C\u002Fem>.\u003C\u002Fp>\u003Ch2 id=\"two-kinds-of-timelines\">Two kinds of timelines\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cstrong>Scroll progress timeline\u003C\u002Fstrong>: progress equals how far a scroll container has been scrolled (0% at the top, 100% at the bottom). Created with \u003Ccode>scroll()\u003C\u002Fcode> or \u003Ccode>scroll-timeline\u003C\u002Fcode>. Best for page progress bars and parallax.\u003C\u002Fli>\u003Cli>\u003Cstrong>View progress timeline\u003C\u002Fstrong>: progress equals how much an element has moved through the scrollport (from entering to leaving). Created with \u003Ccode>view()\u003C\u002Fcode> or \u003Ccode>view-timeline\u003C\u002Fcode>. Best for reveal-on-scroll and per-element effects.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"the-core-syntax\">The core syntax\u003C\u002Fh2>\u003Cp>1) Write normal \u003Ccode>@keyframes\u003C\u002Fcode>. 2) Attach them with \u003Ccode>animation\u003C\u002Fcode> (duration is ignored by scroll timelines, but set \u003Ccode>linear\u003C\u002Fcode> easing in most cases). 3) Set \u003Ccode>animation-timeline\u003C\u002Fcode>.\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode>animation-timeline: scroll()\u003C\u002Fcode>: nearest ancestor scroller. Arguments: scroller (\u003Ccode>nearest\u003C\u002Fcode>, \u003Ccode>root\u003C\u002Fcode>, \u003Ccode>self\u003C\u002Fcode>) and axis (\u003Ccode>block\u003C\u002Fcode>, \u003Ccode>inline\u003C\u002Fcode>, \u003Ccode>y\u003C\u002Fcode>, \u003Ccode>x\u003C\u002Fcode>). Example: \u003Ccode>scroll(root block)\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>\u003Ccode>animation-timeline: view()\u003C\u002Fcode>: progress based on the element's own visibility in the scrollport. You can add an axis and an inset.\u003C\u002Fli>\u003Cli>\u003Cstrong>Named timelines\u003C\u002Fstrong>: \u003Ccode>scroll-timeline-name: --page\u003C\u002Fcode> on a scroller, or \u003Ccode>view-timeline-name: --card\u003C\u002Fcode> on a subject, then \u003Ccode>animation-timeline: --page\u003C\u002Fcode> elsewhere. Use \u003Ccode>timeline-scope\u003C\u002Fcode> to share a timeline with elements that are not descendants.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"animation-range-choose-when-it-plays\">animation-range: choose when it plays\u003C\u002Fh2>\u003Cp>The \u003Ccode>animation-range\u003C\u002Fcode> property limits which part of the timeline drives the animation. For view timelines you can use named ranges:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode>entry\u003C\u002Fcode>: while the element is entering the scrollport.\u003C\u002Fli>\u003Cli>\u003Ccode>exit\u003C\u002Fcode>: while it is leaving.\u003C\u002Fli>\u003Cli>\u003Ccode>cover\u003C\u002Fcode>: from first touching to fully leaving.\u003C\u002Fli>\u003Cli>\u003Ccode>contain\u003C\u002Fcode>: while fully visible inside the scrollport.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Example: \u003Ccode>animation-range: entry 0% entry 100%;\u003C\u002Fcode> makes a reveal finish exactly when the element is fully in view. You can also use \u003Ccode>animation-range: entry 10% cover 40%\u003C\u002Fcode>, or plain lengths and percentages.\u003C\u002Fp>\u003Ch2 id=\"progressive-enhancement-and-fallback\">Progressive enhancement and fallback\u003C\u002Fh2>\u003Cp>Support is excellent in Chromium browsers and is rolling out to others, so treat scroll-driven animation as an enhancement. Wrap it in \u003Ccode>@supports (animation-timeline: scroll())\u003C\u002Fcode>, and make sure the page works with no animation at all. A good rule: elements must be visible and usable by default, and only hidden (for example with \u003Ccode>opacity: 0\u003C\u002Fcode>) inside the \u003Ccode>@supports\u003C\u002Fcode> block. Check current browser support on Can I use before relying on it for essential UI.\u003C\u002Fp>\u003Ch2 id=\"accessibility-and-performance\">Accessibility and performance\u003C\u002Fh2>\u003Cul>\u003Cli>Wrap movement-heavy effects in \u003Ccode>@media (prefers-reduced-motion: no-preference)\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Animate \u003Ccode>transform\u003C\u002Fcode>, \u003Ccode>opacity\u003C\u002Fcode> and \u003Ccode>clip-path\u003C\u002Fcode>. Avoid properties that trigger layout.\u003C\u002Fli>\u003Cli>Avoid parallax that moves large areas quickly, because it can trigger motion sickness.\u003C\u002Fli>\u003Cli>Do not tie critical information (like form errors) to scroll-only reveals.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"common-mistakes\">Common mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Setting the \u003Ccode>animation\u003C\u002Fcode> shorthand after \u003Ccode>animation-timeline\u003C\u002Fcode>. The shorthand resets the timeline, so declare \u003Ccode>animation-timeline\u003C\u002Fcode> \u003Cem>after\u003C\u002Fem> it.\u003C\u002Fli>\u003Cli>Forgetting \u003Ccode>animation-fill-mode: both\u003C\u002Fcode>, so elements flash back to their original state outside the range.\u003C\u002Fli>\u003Cli>Expecting time-based easing. Use \u003Ccode>linear\u003C\u002Fcode> so the animation tracks scroll position exactly.\u003C\u002Fli>\u003Cli>Using \u003Ccode>overflow: hidden\u003C\u002Fcode> on the wrong ancestor, which makes it the nearest scroller instead of the page.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"quick-summary\">Quick summary\u003C\u002Fh2>\u003Cp>\u003Cstrong>CSS scroll-driven animations\u003C\u002Fstrong> use \u003Ccode>animation-timeline\u003C\u002Fcode> with \u003Ccode>scroll()\u003C\u002Fcode> or \u003Ccode>view()\u003C\u002Fcode> to bind keyframes to scrolling, and \u003Ccode>animation-range\u003C\u002Fcode> to choose when they play. Always add \u003Ccode>@supports\u003C\u002Fcode> and reduced-motion guards.\u003C\u002Fp>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .bar { position: fixed; top: 0; left: 0; width: 100%; height: 6px; background: #6366f1; z-index: 10; transform-origin: 0 50%; transform: scaleX(0); }\n  @supports (animation-timeline: scroll()) {\n    .bar { animation: grow linear both; animation-timeline: scroll(root block); }\n  }\n  @keyframes grow { to { transform: scaleX(1); } }\n  article { max-width: 560px; margin: 0 auto; padding: 30px 20px; line-height: 1.7; }\n&lt;\u002Fstyle&gt;\n&lt;div class='bar'&gt;&lt;\u002Fdiv&gt;\n&lt;article id='art'&gt;&lt;\u002Farticle&gt;\n&lt;script&gt;\n  var html = '&lt;h1&gt;Reading progress&lt;\u002Fh1&gt;';\n  for (var i = 1; i &lt;= 25; i++) { html += '&lt;p&gt;Paragraph ' + i + '. Scroll down to watch the bar at the top fill up. The animation is driven by scroll position, not by time.&lt;\u002Fp&gt;'; }\n  document.getElementById('art').innerHTML = html;\n&lt;\u002Fscript&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { margin: 0; font-family: system-ui, sans-serif; background: #f8fafc; }\n  .spacer { height: 70vh; display: grid; place-items: center; color: #64748b; }\n  .card { width: min(420px, 90%); margin: 0 auto 40px; padding: 28px; border-radius: 16px; background: #fff; box-shadow: 0 10px 30px rgba(0,0,0,.08); }\n  @supports (animation-timeline: view()) {\n    @media (prefers-reduced-motion: no-preference) {\n      .card { animation: reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 100%; }\n    }\n  }\n  @keyframes reveal { from { opacity: 0; transform: translateY(60px) scale(.95); } to { opacity: 1; transform: none; } }\n&lt;\u002Fstyle&gt;\n&lt;div class='spacer'&gt;Scroll down&lt;\u002Fdiv&gt;\n&lt;div class='card'&gt;&lt;h3&gt;Card one&lt;\u002Fh3&gt;&lt;p&gt;Fades and slides in as it enters the viewport.&lt;\u002Fp&gt;&lt;\u002Fdiv&gt;\n&lt;div class='card'&gt;&lt;h3&gt;Card two&lt;\u002Fh3&gt;&lt;p&gt;No JavaScript or IntersectionObserver needed.&lt;\u002Fp&gt;&lt;\u002Fdiv&gt;\n&lt;div class='card'&gt;&lt;h3&gt;Card three&lt;\u002Fh3&gt;&lt;p&gt;Content stays visible in browsers without support.&lt;\u002Fp&gt;&lt;\u002Fdiv&gt;\n&lt;div class='card'&gt;&lt;h3&gt;Card four&lt;\u002Fh3&gt;&lt;p&gt;That is progressive enhancement.&lt;\u002Fp&gt;&lt;\u002Fdiv&gt;\n&lt;div class='spacer'&gt;&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .hero { height: 60vh; overflow: hidden; position: relative; display: grid; place-items: center; background: #0f172a; color: #fff; }\n  .hero .bg { position: absolute; inset: -20% 0; background: radial-gradient(circle at 30% 30%, #6366f1, transparent 60%), radial-gradient(circle at 70% 70%, #ec4899, transparent 55%); }\n  .hero h1 { position: relative; margin: 0; font-size: 36px; }\n  @supports (animation-timeline: view()) {\n    @media (prefers-reduced-motion: no-preference) {\n      .hero .bg { animation: parallax linear both; animation-timeline: view(); animation-range: cover; }\n    }\n  }\n  @keyframes parallax { from { transform: translateY(-15%); } to { transform: translateY(15%); } }\n  .content { height: 120vh; padding: 30px; }\n&lt;\u002Fstyle&gt;\n&lt;div class='content'&gt;Scroll down a little to see the parallax hero.&lt;\u002Fdiv&gt;\n&lt;div class='hero'&gt;&lt;div class='bg'&gt;&lt;\u002Fdiv&gt;&lt;h1&gt;Subtle CSS parallax&lt;\u002Fh1&gt;&lt;\u002Fdiv&gt;\n&lt;div class='content'&gt;Keep parallax movement small for comfort.&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .scroller { width: 360px; height: 220px; overflow-y: auto; border: 2px solid #cbd5e1; border-radius: 12px; margin: 20px; position: relative; scroll-timeline: --box block; }\n  .meter { position: sticky; top: 0; height: 6px; background: #10b981; transform-origin: 0 50%; transform: scaleX(0); }\n  @supports (animation-timeline: scroll()) {\n    .meter { animation: fill linear both; animation-timeline: --box; }\n  }\n  @keyframes fill { to { transform: scaleX(1); } }\n  .scroller p { padding: 0 14px; line-height: 1.6; }\n&lt;\u002Fstyle&gt;\n&lt;div class='scroller'&gt;\n  &lt;div class='meter'&gt;&lt;\u002Fdiv&gt;\n  &lt;p&gt;Named scroll timeline on an inner scroll container.&lt;\u002Fp&gt;\n  &lt;p&gt;The meter reads the progress of this box, not the page.&lt;\u002Fp&gt;\n  &lt;p&gt;Keep scrolling inside this box.&lt;\u002Fp&gt;\n  &lt;p&gt;The timeline name is --box.&lt;\u002Fp&gt;\n  &lt;p&gt;Use timeline-scope to share names across siblings.&lt;\u002Fp&gt;\n  &lt;p&gt;Almost there.&lt;\u002Fp&gt;\n  &lt;p&gt;The end.&lt;\u002Fp&gt;\n&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>",{"name":335,"slug":336},{"name":615,"slug":616},{"slug":676,"display_name":677,"job_title":5,"short_bio":5,"expertise_tags":678,"headshot":5,"long_bio":5,"credentials":5,"twitter_url":5,"linkedin_url":5,"github_url":5,"personal_website_url":5,"other_sameas_urls":5,"topics":679,"posts":680},"badar-khalil","Badar Khalil",[],[],[],"Article","https:\u002F\u002Fwpfsharp.com\u002Ftopics\u002Fcss-scroll-driven-animations","CSS Scroll-Driven Animations: scroll() & view() Guide","Learn CSS scroll-driven animations with animation-timeline, scroll(), view(), animation-range, progress bars and reveal effects. Includes fallbacks.",[686,690,694,698,702,706,710,714],{"id":687,"text":688,"level":23,"children":689},"what-are-scroll-driven-animations","What are scroll-driven animations?",[],{"id":691,"text":692,"level":23,"children":693},"two-kinds-of-timelines","Two kinds of timelines",[],{"id":695,"text":696,"level":23,"children":697},"the-core-syntax","The core syntax",[],{"id":699,"text":700,"level":23,"children":701},"animation-range-choose-when-it-plays","animation-range: choose when it plays",[],{"id":703,"text":704,"level":23,"children":705},"progressive-enhancement-and-fallback","Progressive enhancement and fallback",[],{"id":707,"text":708,"level":23,"children":709},"accessibility-and-performance","Accessibility and performance",[],{"id":711,"text":712,"level":23,"children":713},"common-mistakes","Common mistakes",[],{"id":715,"text":716,"level":23,"children":717},"quick-summary","Quick summary",[],[719,723,726,729],{"id":720,"language":652,"code":721,"is_editable":722},591,"\u003Cstyle>\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .bar { position: fixed; top: 0; left: 0; width: 100%; height: 6px; background: #6366f1; z-index: 10; transform-origin: 0 50%; transform: scaleX(0); }\n  @supports (animation-timeline: scroll()) {\n    .bar { animation: grow linear both; animation-timeline: scroll(root block); }\n  }\n  @keyframes grow { to { transform: scaleX(1); } }\n  article { max-width: 560px; margin: 0 auto; padding: 30px 20px; line-height: 1.7; }\n\u003C\u002Fstyle>\n\u003Cdiv class='bar'>\u003C\u002Fdiv>\n\u003Carticle id='art'>\u003C\u002Farticle>\n\u003Cscript>\n  var html = '\u003Ch1>Reading progress\u003C\u002Fh1>';\n  for (var i = 1; i \u003C= 25; i++) { html += '\u003Cp>Paragraph ' + i + '. Scroll down to watch the bar at the top fill up. The animation is driven by scroll position, not by time.\u003C\u002Fp>'; }\n  document.getElementById('art').innerHTML = html;\n\u003C\u002Fscript>",true,{"id":724,"language":652,"code":725,"is_editable":722},592,"\u003Cstyle>\n  body { margin: 0; font-family: system-ui, sans-serif; background: #f8fafc; }\n  .spacer { height: 70vh; display: grid; place-items: center; color: #64748b; }\n  .card { width: min(420px, 90%); margin: 0 auto 40px; padding: 28px; border-radius: 16px; background: #fff; box-shadow: 0 10px 30px rgba(0,0,0,.08); }\n  @supports (animation-timeline: view()) {\n    @media (prefers-reduced-motion: no-preference) {\n      .card { animation: reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 100%; }\n    }\n  }\n  @keyframes reveal { from { opacity: 0; transform: translateY(60px) scale(.95); } to { opacity: 1; transform: none; } }\n\u003C\u002Fstyle>\n\u003Cdiv class='spacer'>Scroll down\u003C\u002Fdiv>\n\u003Cdiv class='card'>\u003Ch3>Card one\u003C\u002Fh3>\u003Cp>Fades and slides in as it enters the viewport.\u003C\u002Fp>\u003C\u002Fdiv>\n\u003Cdiv class='card'>\u003Ch3>Card two\u003C\u002Fh3>\u003Cp>No JavaScript or IntersectionObserver needed.\u003C\u002Fp>\u003C\u002Fdiv>\n\u003Cdiv class='card'>\u003Ch3>Card three\u003C\u002Fh3>\u003Cp>Content stays visible in browsers without support.\u003C\u002Fp>\u003C\u002Fdiv>\n\u003Cdiv class='card'>\u003Ch3>Card four\u003C\u002Fh3>\u003Cp>That is progressive enhancement.\u003C\u002Fp>\u003C\u002Fdiv>\n\u003Cdiv class='spacer'>\u003C\u002Fdiv>",{"id":727,"language":652,"code":728,"is_editable":722},593,"\u003Cstyle>\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .hero { height: 60vh; overflow: hidden; position: relative; display: grid; place-items: center; background: #0f172a; color: #fff; }\n  .hero .bg { position: absolute; inset: -20% 0; background: radial-gradient(circle at 30% 30%, #6366f1, transparent 60%), radial-gradient(circle at 70% 70%, #ec4899, transparent 55%); }\n  .hero h1 { position: relative; margin: 0; font-size: 36px; }\n  @supports (animation-timeline: view()) {\n    @media (prefers-reduced-motion: no-preference) {\n      .hero .bg { animation: parallax linear both; animation-timeline: view(); animation-range: cover; }\n    }\n  }\n  @keyframes parallax { from { transform: translateY(-15%); } to { transform: translateY(15%); } }\n  .content { height: 120vh; padding: 30px; }\n\u003C\u002Fstyle>\n\u003Cdiv class='content'>Scroll down a little to see the parallax hero.\u003C\u002Fdiv>\n\u003Cdiv class='hero'>\u003Cdiv class='bg'>\u003C\u002Fdiv>\u003Ch1>Subtle CSS parallax\u003C\u002Fh1>\u003C\u002Fdiv>\n\u003Cdiv class='content'>Keep parallax movement small for comfort.\u003C\u002Fdiv>",{"id":730,"language":652,"code":731,"is_editable":722},594,"\u003Cstyle>\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  .scroller { width: 360px; height: 220px; overflow-y: auto; border: 2px solid #cbd5e1; border-radius: 12px; margin: 20px; position: relative; scroll-timeline: --box block; }\n  .meter { position: sticky; top: 0; height: 6px; background: #10b981; transform-origin: 0 50%; transform: scaleX(0); }\n  @supports (animation-timeline: scroll()) {\n    .meter { animation: fill linear both; animation-timeline: --box; }\n  }\n  @keyframes fill { to { transform: scaleX(1); } }\n  .scroller p { padding: 0 14px; line-height: 1.6; }\n\u003C\u002Fstyle>\n\u003Cdiv class='scroller'>\n  \u003Cdiv class='meter'>\u003C\u002Fdiv>\n  \u003Cp>Named scroll timeline on an inner scroll container.\u003C\u002Fp>\n  \u003Cp>The meter reads the progress of this box, not the page.\u003C\u002Fp>\n  \u003Cp>Keep scrolling inside this box.\u003C\u002Fp>\n  \u003Cp>The timeline name is --box.\u003C\u002Fp>\n  \u003Cp>Use timeline-scope to share names across siblings.\u003C\u002Fp>\n  \u003Cp>Almost there.\u003C\u002Fp>\n  \u003Cp>The end.\u003C\u002Fp>\n\u003C\u002Fdiv>",[733],{"id":734,"title":735,"slug":736,"prompt":737,"starter_code":738,"expected_output":739,"language":652,"order_index":9},209,"Shrink a sticky header on scroll","scroll-shrink-header","Use animation-timeline: scroll() to shrink the header padding from 24px to 8px and reduce its font size while the user scrolls the first 150px. Use animation-range with lengths, wrap it in @supports, and disable it for users who prefer reduced motion.","\u003Cstyle>\n  body { margin: 0; font-family: system-ui, sans-serif; }\n  header { position: sticky; top: 0; padding: 24px; background: #0f172a; color: #fff; font-size: 28px; }\n  \u002F* TODO: @keyframes shrink *\u002F\n  \u002F* TODO: @supports + animation-timeline + animation-range: 0 150px *\u002F\n  main { height: 200vh; padding: 20px; }\n\u003C\u002Fstyle>\n\u003Cheader>My Site\u003C\u002Fheader>\n\u003Cmain>Scroll down\u003C\u002Fmain>","As you scroll the first 150px, the sticky header smoothly becomes shorter with a smaller title. Browsers without support show the normal header.","2026-09-30T18:50:34+00:00",{"id":631,"slug":633,"title":632},{"id":639,"slug":641,"title":640}]