[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-config":3,"blog-categories":6,"course-tree":35,"topic:css-tooltips-popovers":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,14,19,25,30],{"name":9,"slug":10,"description":11,"post_count":12,"subcategories":13},"CSS","css","Learn CSS with practical tutorials and examples covering layouts, Flexbox, Grid, responsive design, typography, positioning, animations, and more.",2,[],{"name":15,"slug":16,"description":17,"post_count":12,"subcategories":18},"HTML","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":20,"slug":21,"description":22,"post_count":23,"subcategories":24},"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.",1,[],{"name":26,"slug":27,"description":28,"post_count":23,"subcategories":29},"Python","python","Learn Python with practical tutorials covering strings, lists, functions, exceptions, files, packages, virtual environments, modules, classes, and beginner programming concepts.",[],{"name":31,"slug":32,"description":33,"post_count":23,"subcategories":34},"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":36},[37,360],{"id":23,"name":15,"slug":38,"icon":5,"icon_url":5,"short_description":39,"meta_title":40,"meta_description":41,"og_image":42,"locale":43,"subcategories":44},"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",[45,72,108,132,208,242,256,284,308,324],{"id":23,"name":46,"slug":47,"order_index":23,"topics":48},"HTML Fundamentals & Setup","html-fundamentals-setup",[49,53,56,60,64,68],{"id":12,"title":50,"slug":51,"order_index":23,"cornerstone":52,"reading_time_minutes":12},"HTML Editors & Environment Setup","html-editors-and-environment-setup",false,{"id":23,"title":54,"slug":55,"order_index":23,"cornerstone":52,"reading_time_minutes":23},"HTML Introduction & History","html-introduction-and-history",{"id":57,"title":58,"slug":59,"order_index":57,"cornerstone":52,"reading_time_minutes":12},3,"HTML Basic Syntax & Document Structure","html-basic-syntax-document-structure",{"id":61,"title":62,"slug":63,"order_index":61,"cornerstone":52,"reading_time_minutes":12},4,"HTML Elements & Tags Explained","html-elements-tags-explained",{"id":65,"title":66,"slug":67,"order_index":65,"cornerstone":52,"reading_time_minutes":12},5,"HTML Attributes (Global & Standard)","html-attributes-global-standard",{"id":69,"title":70,"slug":71,"order_index":69,"cornerstone":52,"reading_time_minutes":12},6,"Understanding the DOCTYPE & HTML5 Boilerplate","understanding-doctype-html5-boilerplate",{"id":12,"name":73,"slug":74,"order_index":12,"topics":75},"Text & Content Basics","text-content-basics",[76,80,84,88,92,96,100,104],{"id":77,"title":78,"slug":79,"order_index":77,"cornerstone":52,"reading_time_minutes":12},7,"HTML Headings (H1–H6) & SEO Best Practices","html-headings-h1-h6-seo-best-practices",{"id":81,"title":82,"slug":83,"order_index":81,"cornerstone":52,"reading_time_minutes":12},8,"HTML Paragraphs & Line Breaks","html-paragraphs-line-breaks",{"id":85,"title":86,"slug":87,"order_index":85,"cornerstone":52,"reading_time_minutes":23},9,"HTML Text Formatting (Bold, Italic, Mark, etc.)","html-text-formatting-bold-italic-mark",{"id":89,"title":90,"slug":91,"order_index":89,"cornerstone":52,"reading_time_minutes":12},10,"HTML Styles (Inline CSS Basics)","html-styles-inline-css-basics",{"id":93,"title":94,"slug":95,"order_index":93,"cornerstone":52,"reading_time_minutes":12},11,"HTML Quotations & Citations (blockquote, q, cite)","html-quotations-citations-blockquote-q-cite",{"id":97,"title":98,"slug":99,"order_index":97,"cornerstone":52,"reading_time_minutes":12},12,"HTML Comments (Best Practices)","html-comments-best-practices",{"id":101,"title":102,"slug":103,"order_index":101,"cornerstone":52,"reading_time_minutes":12},13,"HTML Colors (Names, HEX, RGB, HSL)","html-colors-names-hex-rgb-hsl",{"id":105,"title":106,"slug":107,"order_index":105,"cornerstone":52,"reading_time_minutes":12},14,"HTML & CSS Integration (Inline, Internal, External)","html-css-integration-inline-internal-external",{"id":57,"name":109,"slug":110,"order_index":57,"topics":111},"Links, Media & Navigation","links-media-navigation",[112,116,120,124,128],{"id":113,"title":114,"slug":115,"order_index":113,"cornerstone":52,"reading_time_minutes":12},15,"HTML Links (Anchor Tags & Hyperlinks)","html-links-anchor-tags-hyperlinks",{"id":117,"title":118,"slug":119,"order_index":117,"cornerstone":52,"reading_time_minutes":12},16,"HTML Images (Alt Text, Lazy Loading, Formats)","html-images-alt-text-lazy-loading-formats",{"id":121,"title":122,"slug":123,"order_index":121,"cornerstone":52,"reading_time_minutes":23},17,"HTML Favicon Setup","html-favicon-setup",{"id":125,"title":126,"slug":127,"order_index":125,"cornerstone":52,"reading_time_minutes":12},18,"HTML Page Title & Meta Tags (SEO Essentials)","html-page-title-meta-tags-seo-essentials",{"id":129,"title":130,"slug":131,"order_index":129,"cornerstone":52,"reading_time_minutes":12},19,"HTML File Paths (Absolute vs Relative)","html-file-paths-absolute-vs-relative",{"id":61,"name":133,"slug":134,"order_index":61,"topics":135},"Structuring Content","structuring-content",[136,141,146,151,156,160,164,168,172,176,180,184,188,192,196,200,204],{"id":137,"title":138,"slug":139,"order_index":140,"cornerstone":52,"reading_time_minutes":12},24,"HTML Tables Explained: Rows, Columns & Merging Cells","html-tables-rows-columns-merging-cells",20,{"id":142,"title":143,"slug":144,"order_index":145,"cornerstone":52,"reading_time_minutes":12},25,"HTML Lists: Ordered, Unordered & Description Lists","html-lists-ordered-unordered-description",21,{"id":147,"title":148,"slug":149,"order_index":150,"cornerstone":52,"reading_time_minutes":12},26,"HTML Block vs Inline Elements Explained","html-block-vs-inline-elements",22,{"id":152,"title":153,"slug":154,"order_index":155,"cornerstone":52,"reading_time_minutes":23},27,"HTML Div & Span: Generic Containers Explained","html-div-and-span-containers",23,{"id":157,"title":158,"slug":159,"order_index":137,"cornerstone":52,"reading_time_minutes":12},28,"HTML Classes vs ID: Selectors Explained","html-classes-vs-id-selectors-explained",{"id":161,"title":162,"slug":163,"order_index":142,"cornerstone":52,"reading_time_minutes":23},29,"HTML Iframes: Embedding External Content","html-iframes-embedding-content",{"id":165,"title":166,"slug":167,"order_index":147,"cornerstone":52,"reading_time_minutes":12},30,"HTML Head Element Deep Dive","html-head-element-deep-dive",{"id":169,"title":170,"slug":171,"order_index":152,"cornerstone":52,"reading_time_minutes":12},31,"HTML Layout Techniques: Header, Nav & Footer","html-layout-techniques-header-nav-footer",{"id":173,"title":174,"slug":175,"order_index":157,"cornerstone":52,"reading_time_minutes":12},32,"Responsive HTML Design: Mobile-First Approach","responsive-html-design-mobile-first-approach",{"id":177,"title":178,"slug":179,"order_index":161,"cornerstone":52,"reading_time_minutes":57},74,"HTML Semantic Elements (article, section, aside, nav)","html-semantic-elements-article-section-aside-nav",{"id":181,"title":182,"slug":183,"order_index":165,"cornerstone":52,"reading_time_minutes":12},75,"HTML Style Guide & Coding Conventions","html-style-guide-coding-conventions",{"id":185,"title":186,"slug":187,"order_index":169,"cornerstone":52,"reading_time_minutes":12},76,"HTML Entities & Special Characters","html-entities-special-characters",{"id":189,"title":190,"slug":191,"order_index":173,"cornerstone":52,"reading_time_minutes":23},77,"HTML Symbols","html-symbols",{"id":193,"title":194,"slug":195,"order_index":193,"cornerstone":52,"reading_time_minutes":23},33,"HTML Emojis 😀: How to Use Them in Web Pages","html-emojis-trending-guide",{"id":197,"title":198,"slug":199,"order_index":197,"cornerstone":52,"reading_time_minutes":12},34,"HTML Character Sets: UTF-8 & Encoding Explained","html-character-sets-utf-8-encoding",{"id":201,"title":202,"slug":203,"order_index":201,"cornerstone":52,"reading_time_minutes":23},35,"HTML URL Encoding Explained","html-url-encoding-explained",{"id":205,"title":206,"slug":207,"order_index":205,"cornerstone":52,"reading_time_minutes":23},36,"HTML vs XHTML: Key Differences","html-vs-xhtml-key-differences",{"id":77,"name":209,"slug":210,"order_index":65,"topics":211},"Forms & User Input","forms-user-input",[212,217,222,227,232,237],{"id":213,"title":214,"slug":215,"order_index":216,"cornerstone":52,"reading_time_minutes":12},49,"HTML Forms Introduction","html-forms-introduction",37,{"id":218,"title":219,"slug":220,"order_index":221,"cornerstone":52,"reading_time_minutes":23},50,"HTML Form Attributes (action, method, etc.)","html-form-attributes-action-method",38,{"id":223,"title":224,"slug":225,"order_index":226,"cornerstone":52,"reading_time_minutes":23},51,"HTML Form Elements (input, select, textarea, button)","html-form-elements-input-select-textarea-button",39,{"id":228,"title":229,"slug":230,"order_index":231,"cornerstone":52,"reading_time_minutes":12},52,"HTML Input Types (Modern Types: email, date, color, range)","html-input-types-modern-email-date-color-range",40,{"id":233,"title":234,"slug":235,"order_index":236,"cornerstone":52,"reading_time_minutes":12},53,"HTML Input Attributes (required, placeholder, pattern)","html-input-attributes-required-placeholder-pattern",41,{"id":238,"title":239,"slug":240,"order_index":241,"cornerstone":52,"reading_time_minutes":12},54,"HTML Form Validation (Client-Side)","html-form-validation-client-side",42,{"id":81,"name":243,"slug":244,"order_index":69,"topics":245},"Graphics & Visuals","graphics-visuals",[246,251],{"id":247,"title":248,"slug":249,"order_index":250,"cornerstone":52,"reading_time_minutes":57},55,"HTML Canvas (2D Drawing API) 🔥","html-canvas-2d-drawing-api",43,{"id":252,"title":253,"slug":254,"order_index":255,"cornerstone":52,"reading_time_minutes":57},56,"HTML SVG (Scalable Vector Graphics)","html-svg-scalable-vector-graphics",44,{"id":85,"name":257,"slug":258,"order_index":77,"topics":259},"Multimedia","multimedia",[260,265,270,275,280],{"id":261,"title":262,"slug":263,"order_index":264,"cornerstone":52,"reading_time_minutes":12},57,"HTML Media Overview","html-media-overview",45,{"id":266,"title":267,"slug":268,"order_index":269,"cornerstone":52,"reading_time_minutes":12},58,"HTML Video Embedding (Native Player)","html-video-embedding-native-player",46,{"id":271,"title":272,"slug":273,"order_index":274,"cornerstone":52,"reading_time_minutes":12},59,"HTML Audio Embedding","html-audio-embedding",47,{"id":276,"title":277,"slug":278,"order_index":279,"cornerstone":52,"reading_time_minutes":12},60,"HTML Plug-ins (Object & Embed Tags)","html-plugins-object-embed-tags",48,{"id":281,"title":282,"slug":283,"order_index":213,"cornerstone":52,"reading_time_minutes":12},61,"Embedding YouTube Videos in HTML","embedding-youtube-videos-in-html",{"id":89,"name":285,"slug":286,"order_index":81,"topics":287},"HTML5 Web APIs (Advanced\u002FTrending)","html5-web-apis-advancedtrending",[288,292,296,300,304],{"id":289,"title":290,"slug":291,"order_index":218,"cornerstone":52,"reading_time_minutes":12},62,"HTML Geolocation API","html-geolocation-api",{"id":293,"title":294,"slug":295,"order_index":223,"cornerstone":52,"reading_time_minutes":12},63,"HTML Drag & Drop API","html-drag-and-drop-api",{"id":297,"title":298,"slug":299,"order_index":228,"cornerstone":52,"reading_time_minutes":12},64,"HTML Web Storage (localStorage & sessionStorage)","html-web-storage-localstorage-sessionstorage",{"id":301,"title":302,"slug":303,"order_index":233,"cornerstone":52,"reading_time_minutes":12},65,"HTML Web Workers (Background Processing)","html-web-workers-background-processing",{"id":305,"title":306,"slug":307,"order_index":238,"cornerstone":52,"reading_time_minutes":12},66,"HTML Server-Sent Events (SSE)","html-server-sent-events-sse",{"id":93,"name":309,"slug":310,"order_index":85,"topics":311},"Accessibility & Best Practices (High-Demand  Skill) �","accessibility-best-practices-high-demand-skill",[312,316,320],{"id":313,"title":314,"slug":315,"order_index":247,"cornerstone":52,"reading_time_minutes":12},67,"HTML Accessibility (ARIA, Screen Readers)","html-accessibility-aria-screen-readers",{"id":317,"title":318,"slug":319,"order_index":252,"cornerstone":52,"reading_time_minutes":12},68,"Writing Semantic & SEO-Friendly HTML","writing-semantic-and-seo-friendly-html",{"id":321,"title":322,"slug":323,"order_index":261,"cornerstone":52,"reading_time_minutes":12},69,"HTML Performance Optimization Basics","html-performance-optimization-basics",{"id":97,"name":325,"slug":326,"order_index":89,"topics":327},"Reference & Practice","reference-practice",[328,332,336,340,344,348,352,356],{"id":329,"title":330,"slug":331,"order_index":23,"cornerstone":52,"reading_time_minutes":12},70,"HTML Tag List (Full Reference)","html-tag-list-full-reference",{"id":333,"title":334,"slug":335,"order_index":12,"cornerstone":52,"reading_time_minutes":12},71,"HTML Global Attributes Reference","html-global-attributes-reference",{"id":337,"title":338,"slug":339,"order_index":57,"cornerstone":52,"reading_time_minutes":12},72,"HTML Events Reference","html-events-reference",{"id":341,"title":342,"slug":343,"order_index":61,"cornerstone":52,"reading_time_minutes":12},73,"HTML Browser Support & Compatibility","html-browser-support-compatibility",{"id":345,"title":346,"slug":347,"order_index":65,"cornerstone":52,"reading_time_minutes":12},78,"HTML Doctypes Reference","html-doctypes-reference",{"id":349,"title":350,"slug":351,"order_index":69,"cornerstone":52,"reading_time_minutes":12},79,"HTTP Methods & Messages (Basics for Forms\u002FAPIs)","http-methods-messages-basics",{"id":353,"title":354,"slug":355,"order_index":77,"cornerstone":52,"reading_time_minutes":57},80,"HTML Interview Preparation (Top Q&A)","html-interview-preparation-top-qa",{"id":357,"title":358,"slug":359,"order_index":81,"cornerstone":52,"reading_time_minutes":23},81,"HTML Quiz & Practice Exercises","html-quiz-practice-exercises",{"id":12,"name":9,"slug":10,"icon":5,"icon_url":5,"short_description":361,"meta_title":362,"meta_description":363,"og_image":5,"locale":43,"subcategories":364},"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.",[365,394,418,454,486,518,550,582,610,638],{"id":155,"name":366,"slug":367,"order_index":368,"topics":369},"UI Components","ui-components",0,[370,374,378,382,386,390],{"id":371,"title":372,"slug":373,"order_index":281,"cornerstone":52,"reading_time_minutes":69},148,"CSS Buttons: Variants, States, Sizes and Accessible Button Design","css-buttons",{"id":375,"title":376,"slug":377,"order_index":289,"cornerstone":52,"reading_time_minutes":69},149,"CSS Card Component: Layouts with Flexbox, Grid, Container Queries and Subgrid","css-cards",{"id":379,"title":380,"slug":381,"order_index":293,"cornerstone":52,"reading_time_minutes":77},150,"CSS Navbar and Dropdown Menus: Responsive, Sticky and Accessible Navigation","css-navbar-dropdowns",{"id":383,"title":384,"slug":385,"order_index":297,"cornerstone":52,"reading_time_minutes":69},151,"HTML and CSS Forms and Inputs: Styled, Accessible and Validated Form Controls","css-forms-inputs",{"id":387,"title":388,"slug":389,"order_index":301,"cornerstone":52,"reading_time_minutes":69},152,"CSS Tooltips and Popovers: Popover API, Anchor Positioning and Accessible Overlays","css-tooltips-popovers",{"id":391,"title":392,"slug":393,"order_index":305,"cornerstone":52,"reading_time_minutes":69},153,"Pagination and Breadcrumbs: Accessible Navigation Patterns with HTML, CSS and Schema","pagination-breadcrumbs",{"id":101,"name":395,"slug":396,"order_index":368,"topics":397},"CSS Fundamentals & Setup","css-fundamentals-setup",[398,402,406,410,414],{"id":399,"title":400,"slug":401,"order_index":23,"cornerstone":52,"reading_time_minutes":61},82,"CSS Introduction & History: What Is CSS and Why It Matters","css-introduction-and-history",{"id":403,"title":404,"slug":405,"order_index":12,"cornerstone":52,"reading_time_minutes":61},83,"CSS Syntax & How Browsers Apply Styles","css-syntax-how-browsers-apply-styles",{"id":407,"title":408,"slug":409,"order_index":57,"cornerstone":52,"reading_time_minutes":57},84,"Setting Up Your CSS Workspace: Linking Files & Live Server","setting-up-css-workspace-linking-files-live-server",{"id":411,"title":412,"slug":413,"order_index":61,"cornerstone":52,"reading_time_minutes":57},85,"CSS Comments & Code Formatting Best Practices","css-comments-and-code-formatting",{"id":415,"title":416,"slug":417,"order_index":65,"cornerstone":52,"reading_time_minutes":65},86,"Browser DevTools for CSS: Inspect, Debug & Edit Styles Live","browser-devtools-for-css",{"id":105,"name":419,"slug":420,"order_index":368,"topics":421},"Selectors & the Cascade","selectors-the-cascade",[422,426,430,434,438,442,446,450],{"id":423,"title":424,"slug":425,"order_index":69,"cornerstone":52,"reading_time_minutes":61},87,"CSS Basic Selectors: Type, Class, ID, Universal & Grouping","css-basic-selectors",{"id":427,"title":428,"slug":429,"order_index":77,"cornerstone":52,"reading_time_minutes":61},88,"CSS Combinators: Descendant, Child, Adjacent & General Sibling","css-combinators",{"id":431,"title":432,"slug":433,"order_index":81,"cornerstone":52,"reading_time_minutes":61},89,"CSS Attribute Selectors: [attr], ^=, $=, *= and More","css-attribute-selectors",{"id":435,"title":436,"slug":437,"order_index":85,"cornerstone":52,"reading_time_minutes":69},90,"CSS Pseudo-classes: :hover, :focus, :nth-child & Modern Selectors","css-pseudo-classes",{"id":439,"title":440,"slug":441,"order_index":89,"cornerstone":52,"reading_time_minutes":65},91,"CSS Pseudo-elements (::before, ::after)","css-pseudo-elements-before-after",{"id":443,"title":444,"slug":445,"order_index":93,"cornerstone":52,"reading_time_minutes":65},92,"Modern CSS Selectors: :is(), :where(), :has()","modern-css-selectors-is-where-has",{"id":447,"title":448,"slug":449,"order_index":97,"cornerstone":52,"reading_time_minutes":61},93,"CSS Specificity Explained","css-specificity-explained",{"id":451,"title":452,"slug":453,"order_index":101,"cornerstone":52,"reading_time_minutes":65},94,"Cascade, Inheritance & !important","css-cascade-inheritance-important",{"id":113,"name":455,"slug":456,"order_index":368,"topics":457},"Colors, Backgrounds & Effects","colors-backgrounds-effects",[458,462,466,470,474,478,482],{"id":459,"title":460,"slug":461,"order_index":105,"cornerstone":52,"reading_time_minutes":65},95,"CSS Colors (HEX, RGB, HSL, OKLCH)","css-colors-hex-rgb-hsl-oklch",{"id":463,"title":464,"slug":465,"order_index":113,"cornerstone":52,"reading_time_minutes":61},96,"CSS Backgrounds","css-backgrounds",{"id":467,"title":468,"slug":469,"order_index":117,"cornerstone":52,"reading_time_minutes":65},97,"CSS Gradients (Linear, Radial, Conic)","css-gradients-linear-radial-conic",{"id":471,"title":472,"slug":473,"order_index":121,"cornerstone":52,"reading_time_minutes":65},98,"CSS Borders, Outlines & Rounded Corners","css-borders-outlines-rounded-corners",{"id":475,"title":476,"slug":477,"order_index":125,"cornerstone":52,"reading_time_minutes":69},99,"CSS Box Shadow & Text Shadow","css-box-shadow-text-shadow",{"id":479,"title":480,"slug":481,"order_index":129,"cornerstone":52,"reading_time_minutes":65},100,"CSS Opacity & Blend Modes","css-opacity-blend-modes",{"id":483,"title":484,"slug":485,"order_index":140,"cornerstone":52,"reading_time_minutes":69},101,"CSS Filters & backdrop-filter (Glassmorphism)","css-filters-backdrop-filter-glassmorphism",{"id":117,"name":487,"slug":488,"order_index":368,"topics":489},"Box Model & Spacing","box-model-spacing",[490,494,498,502,506,510,514],{"id":491,"title":492,"slug":493,"order_index":145,"cornerstone":52,"reading_time_minutes":77},102,"The CSS Box Model: Content, Padding, Border and Margin","css-box-model",{"id":495,"title":496,"slug":497,"order_index":150,"cornerstone":52,"reading_time_minutes":77},103,"CSS Margin and Margin Collapse","css-margin-and-margin-collapse",{"id":499,"title":500,"slug":501,"order_index":155,"cornerstone":52,"reading_time_minutes":69},104,"CSS Padding: Shorthand, Percentages and Best Practices","css-padding",{"id":503,"title":504,"slug":505,"order_index":137,"cornerstone":52,"reading_time_minutes":85},105,"CSS Width, Height, Min-Width, Max-Width, Min-Height & Max-Height","css-width-height-min-max",{"id":507,"title":508,"slug":509,"order_index":142,"cornerstone":52,"reading_time_minutes":65},106,"CSS box-sizing: content-box vs border-box","css-box-sizing",{"id":511,"title":512,"slug":513,"order_index":147,"cornerstone":52,"reading_time_minutes":77},107,"CSS Overflow: hidden, scroll, auto, clip and Text Truncation","css-overflow",{"id":515,"title":516,"slug":517,"order_index":152,"cornerstone":52,"reading_time_minutes":77},108,"CSS Units: px, rem, em, %, vw, vh and dvh","css-units",{"id":121,"name":519,"slug":520,"order_index":368,"topics":521},"Typography & Text","typography-text",[522,526,530,534,538,542,546],{"id":523,"title":524,"slug":525,"order_index":157,"cornerstone":52,"reading_time_minutes":77},109,"CSS Text Properties: Alignment, Spacing, Decoration and Wrapping","css-text-properties",{"id":527,"title":528,"slug":529,"order_index":161,"cornerstone":52,"reading_time_minutes":77},110,"CSS Fonts and font-family: Font Stacks, Weights and System Fonts","css-fonts-font-family",{"id":531,"title":532,"slug":533,"order_index":165,"cornerstone":52,"reading_time_minutes":77},111,"Web Fonts: Google Fonts, @font-face and Variable Fonts","web-fonts",{"id":535,"title":536,"slug":537,"order_index":169,"cornerstone":52,"reading_time_minutes":77},112,"CSS Text Effects: text-wrap balance, line-clamp, Ellipsis and More","css-text-effects",{"id":539,"title":540,"slug":541,"order_index":173,"cornerstone":52,"reading_time_minutes":81},113,"Styling Links","styling-links-css",{"id":543,"title":544,"slug":545,"order_index":193,"cornerstone":52,"reading_time_minutes":77},114,"Styling Lists & Tables","styling-lists-and-tables-css",{"id":547,"title":548,"slug":549,"order_index":197,"cornerstone":52,"reading_time_minutes":89},115,"Icons (SVG & Icon Fonts)","icons-svg-and-icon-fonts",{"id":125,"name":551,"slug":552,"order_index":368,"topics":553},"Display, Position & Layout Basics","display-position-layout-basics",[554,558,562,566,570,574,578],{"id":555,"title":556,"slug":557,"order_index":201,"cornerstone":52,"reading_time_minutes":77},116,"Display & Inline-block","display-and-inline-block",{"id":559,"title":560,"slug":561,"order_index":205,"cornerstone":52,"reading_time_minutes":69},117,"Position (relative, absolute, fixed, sticky)","position-relative-absolute-fixed-sticky",{"id":563,"title":564,"slug":565,"order_index":216,"cornerstone":52,"reading_time_minutes":69},118,"Z-index & Stacking Contexts","z-index-and-stacking-contexts",{"id":567,"title":568,"slug":569,"order_index":221,"cornerstone":52,"reading_time_minutes":65},119,"Float & Clear (Legacy, and Why to Avoid It)","float-and-clear",{"id":571,"title":572,"slug":573,"order_index":226,"cornerstone":52,"reading_time_minutes":69},120,"Centering Techniques","centering-techniques",{"id":575,"title":576,"slug":577,"order_index":231,"cornerstone":52,"reading_time_minutes":77},121,"aspect-ratio & object-fit","aspect-ratio-and-object-fit",{"id":579,"title":580,"slug":581,"order_index":236,"cornerstone":52,"reading_time_minutes":81},122,"Website Layout Basics","website-layout-basics",{"id":140,"name":583,"slug":584,"order_index":368,"topics":585},"The Modern CSS Toolkit","the-modern-css-toolkit",[586,590,594,598,602,606],{"id":587,"title":588,"slug":589,"order_index":241,"cornerstone":52,"reading_time_minutes":81},129,"CSS Variables (Custom Properties)","css-variables-custom-properties",{"id":591,"title":592,"slug":593,"order_index":250,"cornerstone":52,"reading_time_minutes":81},130,"Math Functions (calc, min, max, clamp)","math-functions-calc-min-max-clamp",{"id":595,"title":596,"slug":597,"order_index":255,"cornerstone":52,"reading_time_minutes":77},131,"Native CSS Nesting","native-css-nesting",{"id":599,"title":600,"slug":601,"order_index":264,"cornerstone":52,"reading_time_minutes":77},132,"Cascade Layers (@layer)","cascade-layers-at-layer",{"id":603,"title":604,"slug":605,"order_index":269,"cornerstone":52,"reading_time_minutes":85},133,"Dark Mode (prefers-color-scheme, light-dark())","dark-mode-prefers-color-scheme-light-dark",{"id":607,"title":608,"slug":609,"order_index":274,"cornerstone":52,"reading_time_minutes":81},134,"CSS Reset & Normalize","css-reset-and-normalize",{"id":145,"name":611,"slug":612,"order_index":368,"topics":613},"Responsive Design","responsive-design",[614,618,622,626,630,634],{"id":615,"title":616,"slug":617,"order_index":279,"cornerstone":52,"reading_time_minutes":85},135,"Mobile-First & the Viewport","mobile-first-and-the-viewport",{"id":619,"title":620,"slug":621,"order_index":213,"cornerstone":52,"reading_time_minutes":81},136,"Media Queries","media-queries",{"id":623,"title":624,"slug":625,"order_index":218,"cornerstone":52,"reading_time_minutes":81},137,"Responsive Images & Video","responsive-images-and-video",{"id":627,"title":628,"slug":629,"order_index":223,"cornerstone":52,"reading_time_minutes":85},138,"Fluid Typography with clamp()","fluid-typography-with-clamp",{"id":631,"title":632,"slug":633,"order_index":228,"cornerstone":52,"reading_time_minutes":85},139,"Container Queries","container-queries",{"id":635,"title":636,"slug":637,"order_index":233,"cornerstone":52,"reading_time_minutes":97},140,"Responsive Navigation Pattern","responsive-navigation-pattern",{"id":150,"name":639,"slug":640,"order_index":368,"topics":641},"Transitions & Animation","transitions-animation",[642,646,650,654,658,662,666],{"id":643,"title":644,"slug":645,"order_index":238,"cornerstone":52,"reading_time_minutes":65},141,"CSS Transitions: Smooth State Changes with transition, @starting-style and allow-discrete","css-transitions",{"id":647,"title":648,"slug":649,"order_index":247,"cornerstone":52,"reading_time_minutes":61},142,"CSS 2D Transforms: translate, rotate, scale, skew and transform-origin","css-2d-transforms",{"id":651,"title":652,"slug":653,"order_index":252,"cornerstone":52,"reading_time_minutes":65},143,"CSS 3D Transforms: perspective, preserve-3d, rotateX\u002FY and backface-visibility","css-3d-transforms",{"id":655,"title":656,"slug":657,"order_index":261,"cornerstone":52,"reading_time_minutes":65},144,"CSS Keyframe Animations: @keyframes, animation shorthand, fill-mode and @property","css-keyframe-animations",{"id":659,"title":660,"slug":661,"order_index":266,"cornerstone":52,"reading_time_minutes":65},145,"CSS Scroll-Driven Animations: animation-timeline, scroll() and view()","css-scroll-driven-animations",{"id":663,"title":664,"slug":665,"order_index":271,"cornerstone":52,"reading_time_minutes":65},146,"CSS View Transitions API: Progressive Enhancement for Page and State Animations","css-view-transitions",{"id":667,"title":668,"slug":669,"order_index":276,"cornerstone":52,"reading_time_minutes":69},147,"Motion Accessibility and Performance: prefers-reduced-motion, will-change and Smooth 60fps Animations","motion-accessibility-prefers-reduced-motion-performance",{"data":671},{"id":387,"title":388,"slug":389,"content":672,"course":673,"subcategory":674,"author":675,"reading_time_minutes":69,"cornerstone":52,"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":735,"published_at":5,"updated_at":743,"prev":744,"next":745},"\u003Ch2 id=\"tooltips-vs-popovers\">Tooltips vs popovers\u003C\u002Fh2>\u003Cp>A \u003Cstrong>tooltip\u003C\u002Fstrong> is a small text hint that appears when an element is hovered or focused. A \u003Cstrong>popover\u003C\u002Fstrong> is a larger floating panel that can contain links, buttons, forms or rich content, and is opened by an explicit action such as a click. Choosing the right one is the most important design decision, because each has different accessibility rules.\u003C\u002Fp>\u003Cp>Focus keyword: \u003Cstrong>CSS tooltips and popovers\u003C\u002Fstrong>. Related trending keywords: \u003Cem>Popover API\u003C\u002Fem>, \u003Cem>popovertarget\u003C\u002Fem>, \u003Cem>anchor positioning\u003C\u002Fem>, \u003Cem>position-area\u003C\u002Fem>, \u003Cem>top layer\u003C\u002Fem>, \u003Cem>light dismiss\u003C\u002Fem>, \u003Cem>toggletip\u003C\u002Fem>, \u003Cem>@starting-style popover animation\u003C\u002Fem>, \u003Cem>WCAG 1.4.13\u003C\u002Fem>.\u003C\u002Fp>\u003Ch2 id=\"when-to-use-which\">When to use which\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cstrong>Tooltip\u003C\u002Fstrong>: short, non-essential, text-only supplementary info for a control (for example the name of an icon button). Never put interactive content inside a tooltip.\u003C\u002Fli>\u003Cli>\u003Cstrong>Toggletip\u003C\u002Fstrong>: a click-activated small message, good for help icons. Content is announced with a live region.\u003C\u002Fli>\u003Cli>\u003Cstrong>Popover\u003C\u002Fstrong>: rich or interactive content like menus, filters, profile cards and date pickers.\u003C\u002Fli>\u003Cli>\u003Cstrong>Dialog\u003C\u002Fstrong>: modal content that needs a decision. It blocks the page, unlike a popover.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"tooltip-accessibility-rules\">Tooltip accessibility rules\u003C\u002Fh2>\u003Cul>\u003Cli>Show on \u003Cstrong>hover and keyboard focus\u003C\u002Fstrong>, not hover only.\u003C\u002Fli>\u003Cli>Connect it with \u003Ccode>aria-describedby\u003C\u002Fcode> and give the tooltip \u003Ccode>role='tooltip'\u003C\u002Fcode>. For icon buttons, the name should usually come from \u003Ccode>aria-label\u003C\u002Fcode> and the tooltip is an extra visual.\u003C\u002Fli>\u003Cli>\u003Cstrong>WCAG 1.4.13 Content on Hover or Focus\u003C\u002Fstrong>: the extra content must be \u003Cem>dismissible\u003C\u002Fem> (Escape closes it without moving pointer or focus), \u003Cem>hoverable\u003C\u002Fem> (the pointer can move onto it without it disappearing) and \u003Cem>persistent\u003C\u002Fem> (it stays until dismissed or no longer relevant).\u003C\u002Fli>\u003Cli>Do not put essential information only in a tooltip, since touch users cannot hover.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"the-popover-api\">The Popover API\u003C\u002Fh2>\u003Cp>The HTML \u003Ccode>popover\u003C\u002Fcode> attribute turns any element into a popover that is shown in the \u003Cstrong>top layer\u003C\u002Fstrong>, so it is never clipped by \u003Ccode>overflow: hidden\u003C\u002Fcode> and does not need \u003Ccode>z-index\u003C\u002Fcode>. Connect a button with \u003Ccode>popovertarget='id'\u003C\u002Fcode>; no JavaScript is required.\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode>popover\u003C\u002Fcode> (same as \u003Ccode>popover='auto'\u003C\u002Fcode>): light dismiss (click outside or press Escape closes it) and only one auto popover is open at a time.\u003C\u002Fli>\u003Cli>\u003Ccode>popover='manual'\u003C\u002Fcode>: no light dismiss, you control opening and closing. Good for toasts.\u003C\u002Fli>\u003Cli>Methods: \u003Ccode>showPopover()\u003C\u002Fcode>, \u003Ccode>hidePopover()\u003C\u002Fcode>, \u003Ccode>togglePopover()\u003C\u002Fcode>. Events: \u003Ccode>beforetoggle\u003C\u002Fcode> and \u003Ccode>toggle\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Style the open state with \u003Ccode>:popover-open\u003C\u002Fcode> and the backdrop with \u003Ccode>::backdrop\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>The browser provides focus return and basic accessibility, but you still need a good trigger label and meaningful content.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"animating-popovers\">Animating popovers\u003C\u002Fh2>\u003Cp>Because popovers change between \u003Ccode>display: none\u003C\u002Fcode> and shown, animate them with \u003Ccode>@starting-style\u003C\u002Fcode> and \u003Ccode>transition-behavior: allow-discrete\u003C\u002Fcode>: set \u003Ccode>transition: opacity .25s, transform .25s, overlay .25s allow-discrete, display .25s allow-discrete;\u003C\u002Fcode>. Define the closed style on \u003Ccode>[popover]\u003C\u002Fcode>, the open style on \u003Ccode>:popover-open\u003C\u002Fcode>, and the starting style inside \u003Ccode>@starting-style\u003C\u002Fcode>.\u003C\u002Fp>\u003Ch2 id=\"css-anchor-positioning\">CSS anchor positioning\u003C\u002Fh2>\u003Cp>Anchor positioning lets you attach a floating element to another element in pure CSS, replacing JavaScript positioning libraries in many cases. Give the trigger \u003Ccode>anchor-name: --tip\u003C\u002Fcode>; on the popover use \u003Ccode>position: fixed; position-anchor: --tip; position-area: top;\u003C\u002Fcode> (or \u003Ccode>bottom\u003C\u002Fcode>, \u003Ccode>left\u003C\u002Fcode>, \u003Ccode>right\u003C\u002Fcode>, \u003Ccode>top span-right\u003C\u002Fcode>). Use \u003Ccode>position-try-fallbacks: flip-block\u003C\u002Fcode> so it flips when there is no room. Because support is still growing, treat it as progressive enhancement: wrap it in \u003Ccode>@supports (position-anchor: --a)\u003C\u002Fcode> and keep a simple fallback position.\u003C\u002Fp>\u003Ch2 id=\"best-practices\">Best practices\u003C\u002Fh2>\u003Cul>\u003Cli>Keep tooltip text short (under about 80 characters).\u003C\u002Fli>\u003Cli>Provide sufficient contrast and a pointer arrow only if it adds clarity.\u003C\u002Fli>\u003Cli>Do not cover the trigger itself or important nearby content.\u003C\u002Fli>\u003Cli>Respect \u003Ccode>prefers-reduced-motion\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Test with keyboard only, a screen reader and on touch devices.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"quick-summary\">Quick summary\u003C\u002Fh2>\u003Cp>Use tooltips for short, non-essential hints with hover and focus support, toggletips for click-activated help, and the Popover API plus anchor positioning for rich floating panels. That gives accessible \u003Cstrong>CSS tooltips and popovers\u003C\u002Fstrong> with very little JavaScript.\u003C\u002Fp>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { font-family: system-ui, sans-serif; padding: 80px 40px; }\n  .tip { position: relative; display: inline-block; }\n  .tip button { padding: 10px 16px; border: 0; border-radius: 10px; background: #4f46e5; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  .tip button:focus-visible { outline: 3px solid #f59e0b; outline-offset: 3px; }\n  .tip [role='tooltip'] { position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%) translateY(4px); padding: 8px 12px; background: #0f172a; color: #fff; font-size: 13px; border-radius: 8px; white-space: nowrap; opacity: 0; visibility: hidden; transition: opacity .15s, transform .15s, visibility .15s; }\n  .tip [role='tooltip']::after { content: ''; position: absolute; top: 100%; left: 50%; margin-left: -6px; border: 6px solid transparent; border-top-color: #0f172a; }\n  .tip:hover [role='tooltip'], .tip:focus-within [role='tooltip'] { opacity: 1; visibility: visible; transform: translateX(-50%); }\n  \u002F* WCAG 1.4.13: Escape dismisses *\u002F\n  .tip.dismissed [role='tooltip'] { opacity: 0; visibility: hidden; }\n  @media (prefers-reduced-motion: reduce) { .tip [role='tooltip'] { transition: none; } }\n&lt;\u002Fstyle&gt;\n&lt;span class='tip' id='tip'&gt;\n  &lt;button aria-describedby='t1'&gt;Hover or focus me&lt;\u002Fbutton&gt;\n  &lt;span role='tooltip' id='t1'&gt;Saves your work to the cloud&lt;\u002Fspan&gt;\n&lt;\u002Fspan&gt;\n&lt;script&gt;\n  var tip = document.getElementById('tip');\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape') tip.classList.add('dismissed'); });\n  tip.addEventListener('mouseleave', function () { tip.classList.remove('dismissed'); });\n  tip.addEventListener('focusout', function () { tip.classList.remove('dismissed'); });\n&lt;\u002Fscript&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { font-family: system-ui, sans-serif; padding: 30px; }\n  .open-btn { padding: 10px 18px; border: 0; border-radius: 10px; background: #0f766e; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  [popover] { padding: 18px; border: 0; border-radius: 14px; box-shadow: 0 16px 40px rgba(0,0,0,.25); max-width: 280px; }\n  [popover] h3 { margin: 0 0 6px; }\n  [popover] p { margin: 0 0 12px; color: #475569; }\n  [popover] button { padding: 8px 14px; border: 0; border-radius: 8px; background: #e2e8f0; cursor: pointer; }\n&lt;\u002Fstyle&gt;\n&lt;button class='open-btn' popovertarget='pop'&gt;Open popover&lt;\u002Fbutton&gt;\n&lt;div id='pop' popover&gt;\n  &lt;h3&gt;Hello popover&lt;\u002Fh3&gt;\n  &lt;p&gt;No JavaScript needed. Press Escape or click outside to close (light dismiss).&lt;\u002Fp&gt;\n  &lt;button popovertarget='pop' popovertargetaction='hide'&gt;Close&lt;\u002Fbutton&gt;\n&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { font-family: system-ui, sans-serif; padding: 30px; }\n  .open-btn { padding: 10px 18px; border: 0; border-radius: 10px; background: #7c3aed; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  #menu { padding: 16px 20px; border: 0; border-radius: 14px; box-shadow: 0 16px 40px rgba(0,0,0,.25); opacity: 0; transform: translateY(12px) scale(.96); transition: opacity .25s, transform .25s, overlay .25s allow-discrete, display .25s allow-discrete; }\n  #menu:popover-open { opacity: 1; transform: none; }\n  @starting-style { #menu:popover-open { opacity: 0; transform: translateY(12px) scale(.96); } }\n  #menu::backdrop { background: rgba(15,23,42,0); transition: background-color .25s, overlay .25s allow-discrete, display .25s allow-discrete; }\n  #menu:popover-open::backdrop { background: rgba(15,23,42,.35); }\n  @starting-style { #menu:popover-open::backdrop { background: rgba(15,23,42,0); } }\n  @media (prefers-reduced-motion: reduce) { #menu, #menu::backdrop { transition: none; } }\n&lt;\u002Fstyle&gt;\n&lt;button class='open-btn' popovertarget='menu'&gt;Animated popover&lt;\u002Fbutton&gt;\n&lt;div id='menu' popover&gt;\n  &lt;strong&gt;Quick actions&lt;\u002Fstrong&gt;\n  &lt;p style='margin:8px 0 0'&gt;Animated with @starting-style and allow-discrete.&lt;\u002Fp&gt;\n&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { font-family: system-ui, sans-serif; padding: 120px 40px; }\n  .anchor-btn { anchor-name: --help; padding: 10px 18px; border: 0; border-radius: 10px; background: #0ea5e9; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  .pop { margin: 0; inset: auto; padding: 12px 16px; border: 0; border-radius: 12px; background: #0f172a; color: #fff; max-width: 240px; box-shadow: 0 12px 30px rgba(0,0,0,.3); }\n  \u002F* Progressive enhancement: position next to the trigger in CSS *\u002F\n  @supports (position-anchor: --help) {\n    .pop { position: fixed; position-anchor: --help; position-area: top; margin-bottom: 10px; position-try-fallbacks: flip-block; }\n  }\n&lt;\u002Fstyle&gt;\n&lt;button class='anchor-btn' popovertarget='p'&gt;Anchored popover&lt;\u002Fbutton&gt;\n&lt;div class='pop' id='p' popover&gt;Positioned with CSS anchor positioning. It flips below when there is no room above.&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { font-family: system-ui, sans-serif; padding: 40px; }\n  .wrap { position: relative; display: inline-block; }\n  .help { width: 32px; height: 32px; border-radius: 50%; border: 2px solid #4f46e5; background: #fff; color: #4f46e5; font-weight: 800; cursor: pointer; }\n  .help:focus-visible { outline: 3px solid #f59e0b; outline-offset: 3px; }\n  .bubble { position: absolute; left: 0; top: calc(100% + 8px); width: 240px; padding: 10px 14px; background: #eef2ff; color: #1e1b4b; border-radius: 10px; box-shadow: 0 8px 20px rgba(0,0,0,.15); font-size: 14px; }\n  .bubble:empty { display: none; }\n&lt;\u002Fstyle&gt;\n&lt;div class='wrap'&gt;\n  &lt;button class='help' id='h' aria-label='More information about passwords'&gt;?&lt;\u002Fbutton&gt;\n  &lt;div class='bubble' id='b' role='status' aria-live='polite'&gt;&lt;\u002Fdiv&gt;\n&lt;\u002Fdiv&gt;\n&lt;script&gt;\n  var h = document.getElementById('h'), b = document.getElementById('b');\n  h.addEventListener('click', function () { b.textContent = b.textContent ? '' : 'Use at least 12 characters with a mix of words.'; });\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape') b.textContent = ''; });\n  document.addEventListener('click', function (e) { if (!h.contains(e.target)) b.textContent = ''; });\n&lt;\u002Fscript&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>",{"name":9,"slug":10},{"name":366,"slug":367},{"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-tooltips-popovers","CSS Tooltips & Popover API: Accessible Overlays Guide","Build tooltips and popovers with the Popover API, anchor positioning, top layer, @starting-style animation and WCAG 1.4.13 accessibility rules.",[686,690,694,698,702,706,710,714],{"id":687,"text":688,"level":12,"children":689},"tooltips-vs-popovers","Tooltips vs popovers",[],{"id":691,"text":692,"level":12,"children":693},"when-to-use-which","When to use which",[],{"id":695,"text":696,"level":12,"children":697},"tooltip-accessibility-rules","Tooltip accessibility rules",[],{"id":699,"text":700,"level":12,"children":701},"the-popover-api","The Popover API",[],{"id":703,"text":704,"level":12,"children":705},"animating-popovers","Animating popovers",[],{"id":707,"text":708,"level":12,"children":709},"css-anchor-positioning","CSS anchor positioning",[],{"id":711,"text":712,"level":12,"children":713},"best-practices","Best practices",[],{"id":715,"text":716,"level":12,"children":717},"quick-summary","Quick summary",[],[719,723,726,729,732],{"id":720,"language":16,"code":721,"is_editable":722},624,"\u003Cstyle>\n  body { font-family: system-ui, sans-serif; padding: 80px 40px; }\n  .tip { position: relative; display: inline-block; }\n  .tip button { padding: 10px 16px; border: 0; border-radius: 10px; background: #4f46e5; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  .tip button:focus-visible { outline: 3px solid #f59e0b; outline-offset: 3px; }\n  .tip [role='tooltip'] { position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%) translateY(4px); padding: 8px 12px; background: #0f172a; color: #fff; font-size: 13px; border-radius: 8px; white-space: nowrap; opacity: 0; visibility: hidden; transition: opacity .15s, transform .15s, visibility .15s; }\n  .tip [role='tooltip']::after { content: ''; position: absolute; top: 100%; left: 50%; margin-left: -6px; border: 6px solid transparent; border-top-color: #0f172a; }\n  .tip:hover [role='tooltip'], .tip:focus-within [role='tooltip'] { opacity: 1; visibility: visible; transform: translateX(-50%); }\n  \u002F* WCAG 1.4.13: Escape dismisses *\u002F\n  .tip.dismissed [role='tooltip'] { opacity: 0; visibility: hidden; }\n  @media (prefers-reduced-motion: reduce) { .tip [role='tooltip'] { transition: none; } }\n\u003C\u002Fstyle>\n\u003Cspan class='tip' id='tip'>\n  \u003Cbutton aria-describedby='t1'>Hover or focus me\u003C\u002Fbutton>\n  \u003Cspan role='tooltip' id='t1'>Saves your work to the cloud\u003C\u002Fspan>\n\u003C\u002Fspan>\n\u003Cscript>\n  var tip = document.getElementById('tip');\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape') tip.classList.add('dismissed'); });\n  tip.addEventListener('mouseleave', function () { tip.classList.remove('dismissed'); });\n  tip.addEventListener('focusout', function () { tip.classList.remove('dismissed'); });\n\u003C\u002Fscript>",true,{"id":724,"language":16,"code":725,"is_editable":722},625,"\u003Cstyle>\n  body { font-family: system-ui, sans-serif; padding: 30px; }\n  .open-btn { padding: 10px 18px; border: 0; border-radius: 10px; background: #0f766e; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  [popover] { padding: 18px; border: 0; border-radius: 14px; box-shadow: 0 16px 40px rgba(0,0,0,.25); max-width: 280px; }\n  [popover] h3 { margin: 0 0 6px; }\n  [popover] p { margin: 0 0 12px; color: #475569; }\n  [popover] button { padding: 8px 14px; border: 0; border-radius: 8px; background: #e2e8f0; cursor: pointer; }\n\u003C\u002Fstyle>\n\u003Cbutton class='open-btn' popovertarget='pop'>Open popover\u003C\u002Fbutton>\n\u003Cdiv id='pop' popover>\n  \u003Ch3>Hello popover\u003C\u002Fh3>\n  \u003Cp>No JavaScript needed. Press Escape or click outside to close (light dismiss).\u003C\u002Fp>\n  \u003Cbutton popovertarget='pop' popovertargetaction='hide'>Close\u003C\u002Fbutton>\n\u003C\u002Fdiv>",{"id":727,"language":16,"code":728,"is_editable":722},626,"\u003Cstyle>\n  body { font-family: system-ui, sans-serif; padding: 30px; }\n  .open-btn { padding: 10px 18px; border: 0; border-radius: 10px; background: #7c3aed; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  #menu { padding: 16px 20px; border: 0; border-radius: 14px; box-shadow: 0 16px 40px rgba(0,0,0,.25); opacity: 0; transform: translateY(12px) scale(.96); transition: opacity .25s, transform .25s, overlay .25s allow-discrete, display .25s allow-discrete; }\n  #menu:popover-open { opacity: 1; transform: none; }\n  @starting-style { #menu:popover-open { opacity: 0; transform: translateY(12px) scale(.96); } }\n  #menu::backdrop { background: rgba(15,23,42,0); transition: background-color .25s, overlay .25s allow-discrete, display .25s allow-discrete; }\n  #menu:popover-open::backdrop { background: rgba(15,23,42,.35); }\n  @starting-style { #menu:popover-open::backdrop { background: rgba(15,23,42,0); } }\n  @media (prefers-reduced-motion: reduce) { #menu, #menu::backdrop { transition: none; } }\n\u003C\u002Fstyle>\n\u003Cbutton class='open-btn' popovertarget='menu'>Animated popover\u003C\u002Fbutton>\n\u003Cdiv id='menu' popover>\n  \u003Cstrong>Quick actions\u003C\u002Fstrong>\n  \u003Cp style='margin:8px 0 0'>Animated with @starting-style and allow-discrete.\u003C\u002Fp>\n\u003C\u002Fdiv>",{"id":730,"language":16,"code":731,"is_editable":722},627,"\u003Cstyle>\n  body { font-family: system-ui, sans-serif; padding: 120px 40px; }\n  .anchor-btn { anchor-name: --help; padding: 10px 18px; border: 0; border-radius: 10px; background: #0ea5e9; color: #fff; font: 600 15px system-ui; cursor: pointer; }\n  .pop { margin: 0; inset: auto; padding: 12px 16px; border: 0; border-radius: 12px; background: #0f172a; color: #fff; max-width: 240px; box-shadow: 0 12px 30px rgba(0,0,0,.3); }\n  \u002F* Progressive enhancement: position next to the trigger in CSS *\u002F\n  @supports (position-anchor: --help) {\n    .pop { position: fixed; position-anchor: --help; position-area: top; margin-bottom: 10px; position-try-fallbacks: flip-block; }\n  }\n\u003C\u002Fstyle>\n\u003Cbutton class='anchor-btn' popovertarget='p'>Anchored popover\u003C\u002Fbutton>\n\u003Cdiv class='pop' id='p' popover>Positioned with CSS anchor positioning. It flips below when there is no room above.\u003C\u002Fdiv>",{"id":733,"language":16,"code":734,"is_editable":722},628,"\u003Cstyle>\n  body { font-family: system-ui, sans-serif; padding: 40px; }\n  .wrap { position: relative; display: inline-block; }\n  .help { width: 32px; height: 32px; border-radius: 50%; border: 2px solid #4f46e5; background: #fff; color: #4f46e5; font-weight: 800; cursor: pointer; }\n  .help:focus-visible { outline: 3px solid #f59e0b; outline-offset: 3px; }\n  .bubble { position: absolute; left: 0; top: calc(100% + 8px); width: 240px; padding: 10px 14px; background: #eef2ff; color: #1e1b4b; border-radius: 10px; box-shadow: 0 8px 20px rgba(0,0,0,.15); font-size: 14px; }\n  .bubble:empty { display: none; }\n\u003C\u002Fstyle>\n\u003Cdiv class='wrap'>\n  \u003Cbutton class='help' id='h' aria-label='More information about passwords'>?\u003C\u002Fbutton>\n  \u003Cdiv class='bubble' id='b' role='status' aria-live='polite'>\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cscript>\n  var h = document.getElementById('h'), b = document.getElementById('b');\n  h.addEventListener('click', function () { b.textContent = b.textContent ? '' : 'Use at least 12 characters with a mix of words.'; });\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape') b.textContent = ''; });\n  document.addEventListener('click', function (e) { if (!h.contains(e.target)) b.textContent = ''; });\n\u003C\u002Fscript>",[736],{"id":737,"title":738,"slug":739,"prompt":740,"starter_code":741,"expected_output":742,"language":16,"order_index":23},216,"Make a WCAG 1.4.13 compliant tooltip","wcag-compliant-tooltip","Finish the tooltip so it shows on hover and on keyboard focus, is connected with aria-describedby, stays visible when the pointer moves onto the tooltip (hoverable) and closes when Escape is pressed (dismissible).","\u003Cstyle>\n  .tip { position: relative; display: inline-block; margin: 60px; }\n  .tip [role='tooltip'] { position: absolute; bottom: 100%; left: 0; padding: 6px 10px; background: #0f172a; color: #fff; border-radius: 6px; font-size: 13px; visibility: hidden; }\n  \u002F* TODO: show on hover and focus-within; keep hoverable; hide on Escape via class *\u002F\n\u003C\u002Fstyle>\n\u003Cspan class='tip'>\n  \u003Cbutton>Info\u003C\u002Fbutton>\n  \u003Cspan role='tooltip' id='tt'>Helpful extra detail\u003C\u002Fspan>\n\u003C\u002Fspan>\n\u003Cscript>\n  \u002F\u002F TODO: aria-describedby and Escape handler\n\u003C\u002Fscript>","The tooltip shows on hover and focus, remains visible while the pointer is over it, and disappears when Escape is pressed.","2026-09-30T18:59:00+00:00",{"id":383,"slug":385,"title":384},{"id":391,"slug":393,"title":392}]