[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-config":3,"blog-categories":6,"course-tree":35,"topic:responsive-navigation-pattern":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":635,"title":636,"slug":637,"content":672,"course":673,"subcategory":674,"author":675,"reading_time_minutes":97,"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":742,"quiz":5,"exercises":766,"published_at":5,"updated_at":781,"prev":782,"next":783},"\u003Ch2 id=\"responsive-navigation-patterns-accessible-and-mobile-first\">Responsive Navigation Patterns: Accessible and Mobile-First\u003C\u002Fh2>\u003Cp>\u003Cstrong>Focus keyword: responsive navigation.\u003C\u002Fstrong> Navigation is the part of a website that must work for everyone: on a small phone with a thumb, on a desktop with a mouse, with a keyboard and with a screen reader. In this lesson you will learn the common responsive navigation patterns, how to build a mobile-first menu with a hamburger button, how to make it accessible with aria-expanded and keyboard support, how to build an off-canvas drawer and a dropdown submenu, and how to avoid the mistakes that make menus unusable.\u003C\u002Fp>\u003Ch3 id=\"trending-keywords-covered-in-this-lesson\">Trending keywords covered in this lesson\u003C\u002Fh3>\u003Cp>responsive navigation menu, hamburger menu CSS, mobile-first navbar, aria-expanded aria-controls, accessible menu button, disclosure navigation pattern, off-canvas menu, slide-in drawer, dropdown menu focus-within, bottom navigation bar, sticky header, priority plus navigation, skip link, Escape key close menu, focus management, details summary menu, popover attribute, prefers-reduced-motion, touch target 44px, aria-current page.\u003C\u002Fp>\u003Ch2 id=\"1-common-responsive-navigation-patterns\">1. Common Responsive Navigation Patterns\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cstrong>Inline links that wrap:\u003C\u002Fstrong> the simplest choice for sites with only a few links. Use flexbox with \u003Ccode>flex-wrap: wrap\u003C\u002Fcode> and \u003Ccode>gap\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>\u003Cstrong>Hamburger (toggle) menu:\u003C\u002Fstrong> links are hidden behind a Menu button on small screens and shown as a row on large screens. The most common pattern.\u003C\u002Fli>\u003Cli>\u003Cstrong>Off-canvas drawer:\u003C\u002Fstrong> the menu slides in from the side over a dimmed overlay.\u003C\u002Fli>\u003Cli>\u003Cstrong>Bottom tab bar:\u003C\u002Fstrong> three to five main destinations fixed at the bottom of a phone, which is easy to reach with a thumb. Good for app-like sites.\u003C\u002Fli>\u003Cli>\u003Cstrong>Priority plus:\u003C\u002Fstrong> show as many links as fit and move the rest to a More menu. It needs JavaScript or container queries.\u003C\u002Fli>\u003Cli>\u003Cstrong>Mega menu:\u003C\u002Fstrong> large panels with many links on desktop. Convert it to an accordion on mobile.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Choose the simplest pattern that fits your number of links. Hiding navigation behind a button reduces discoverability, so do not use a hamburger on desktop where there is room.\u003C\u002Fp>\u003Ch2 id=\"2-semantic-html-first\">2. Semantic HTML First\u003C\u002Fh2>\u003Cul>\u003Cli>Wrap the main links in \u003Ccode>&lt;nav aria-label='Main'&gt;\u003C\u002Fcode>. Give each nav landmark a different label when a page has more than one.\u003C\u002Fli>\u003Cli>Use a list: \u003Ccode>ul\u003C\u002Fcode> with \u003Ccode>li\u003C\u002Fcode> and \u003Ccode>a\u003C\u002Fcode>. Screen readers announce the number of items.\u003C\u002Fli>\u003Cli>Mark the current page with \u003Ccode>aria-current='page'\u003C\u002Fcode> and style it with \u003Ccode>[aria-current='page']\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Add a \u003Cstrong>skip link\u003C\u002Fstrong> at the start of the page so keyboard users can jump to the main content.\u003C\u002Fli>\u003Cli>Use real links for navigation and real buttons for actions like opening a menu. Never use a div as the menu button.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"3-the-mobile-first-toggle-menu\">3. The Mobile-First Toggle Menu\u003C\u002Fh2>\u003Cp>Write the small screen version as the base: the menu is hidden and the button is visible. At the breakpoint, hide the button and show the menu as a row.\u003C\u002Fp>\u003Cul>\u003Cli>The button needs a visible text label or an \u003Ccode>aria-label\u003C\u002Fcode>. An icon alone is not enough for assistive technology.\u003C\u002Fli>\u003Cli>Add \u003Ccode>aria-expanded='false'\u003C\u002Fcode> and \u003Ccode>aria-controls='menu-id'\u003C\u002Fcode>. JavaScript switches aria-expanded between false and true.\u003C\u002Fli>\u003Cli>Hide the menu with \u003Ccode>display: none\u003C\u002Fcode> (or \u003Ccode>visibility: hidden\u003C\u002Fcode> or the \u003Ccode>hidden\u003C\u002Fcode> attribute) so hidden links are not reachable with the keyboard or screen readers.\u003C\u002Fli>\u003Cli>Use \u003Cstrong>the disclosure pattern\u003C\u002Fstrong>, which is a button that shows and hides content. Avoid \u003Ccode>role='menu'\u003C\u002Fcode>, \u003Ccode>role='menuitem'\u003C\u002Fcode> and \u003Ccode>aria-haspopup\u003C\u002Fcode> for site navigation. Those roles are for application menus and require complex keyboard handling.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"4-keyboard-and-focus-behavior\">4. Keyboard and Focus Behavior\u003C\u002Fh2>\u003Cul>\u003Cli>The button must work with Enter and Space. A native button does this for free.\u003C\u002Fli>\u003Cli>Pressing \u003Cstrong>Escape\u003C\u002Fstrong> should close the open menu and return focus to the button.\u003C\u002Fli>\u003Cli>In an off-canvas drawer, move focus to the first link when opened and return it to the button when closed. A fully modal drawer should trap focus inside, and the page behind it should be inert.\u003C\u002Fli>\u003Cli>Use \u003Ccode>:focus-visible\u003C\u002Fcode> for a clear focus ring and never remove it without a replacement.\u003C\u002Fli>\u003Cli>Close the menu when a link is clicked in a single page site, and when the viewport grows to the desktop breakpoint.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"5-off-canvas-drawer\">5. Off-Canvas Drawer\u003C\u002Fh2>\u003Cp>Position the drawer with \u003Ccode>position: fixed\u003C\u002Fcode>, move it out of view with \u003Ccode>transform: translateX(-100%)\u003C\u002Fcode> and bring it in by removing the transform. Use \u003Ccode>visibility: hidden\u003C\u002Fcode> when closed and transition visibility together with transform, so a closed drawer is not focusable. Add an overlay element that closes the menu when clicked. Lock page scrolling with \u003Ccode>overflow: hidden\u003C\u002Fcode> on the body while open. Respect \u003Ccode>prefers-reduced-motion\u003C\u002Fcode> by removing the transition. The native \u003Ccode>&lt;dialog&gt;\u003C\u002Fcode> element with \u003Ccode>showModal()\u003C\u002Fcode> gives focus trapping, the Escape key and an inert background for free, and the \u003Ccode>popover\u003C\u002Fcode> attribute offers light-dismiss behavior for simpler menus.\u003C\u002Fp>\u003Ch2 id=\"6-dropdown-submenus\">6. Dropdown Submenus\u003C\u002Fh2>\u003Cul>\u003Cli>\u003Cstrong>Hover only is not enough.\u003C\u002Fstrong> Open the submenu on \u003Ccode>:hover\u003C\u002Fcode> and on \u003Ccode>:focus-within\u003C\u002Fcode> so keyboard users can use it, and provide a button with \u003Ccode>aria-expanded\u003C\u002Fcode> for touch screens.\u003C\u002Fli>\u003Cli>A simple no-JavaScript option is \u003Ccode>details\u003C\u002Fcode> and \u003Ccode>summary\u003C\u002Fcode>, which is keyboard accessible by default.\u003C\u002Fli>\u003Cli>Make sure there is no gap between the parent and the submenu so the pointer does not lose hover while moving.\u003C\u002Fli>\u003Cli>Do not build deep multi-level flyouts. Two levels are the maximum for usability.\u003C\u002Fli>\u003Cli>Wrap hover effects in \u003Ccode>@media (hover: hover)\u003C\u002Fcode>.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"7-bottom-tab-bar\">7. Bottom Tab Bar\u003C\u002Fh2>\u003Cp>Fix the bar to the bottom on small screens and add \u003Ccode>padding-bottom: env(safe-area-inset-bottom)\u003C\u002Fcode> with \u003Ccode>viewport-fit=cover\u003C\u002Fcode> so gesture bars do not cover it. Use three to five items with an icon and a short label. Add bottom padding to the page so the bar does not cover the last content. At the desktop breakpoint, change it to a normal top navigation with \u003Ccode>position: static\u003C\u002Fcode>.\u003C\u002Fp>\u003Ch2 id=\"8-sticky-header\">8. Sticky Header\u003C\u002Fh2>\u003Cp>A sticky header uses \u003Ccode>position: sticky; top: 0\u003C\u002Fcode> with a z-index from your scale. Keep it short on small screens because it uses valuable space. Combine it with \u003Ccode>scroll-margin-top\u003C\u002Fcode> on headings so anchor links do not hide under it. Make sure the header never covers the focused element, which WCAG 2.2 calls focus not obscured.\u003C\u002Fp>\u003Ch2 id=\"9-touch-target-size-and-spacing\">9. Touch Target Size and Spacing\u003C\u002Fh2>\u003Cp>Links and buttons in the navigation should be at least 44 CSS pixels tall on touch screens, with enough space between them. Use padding on the link instead of margin around it, so the whole area is clickable.\u003C\u002Fp>\u003Ch2 id=\"10-test-your-navigation\">10. Test Your Navigation\u003C\u002Fh2>\u003Col>\u003Cli>Use only the keyboard: Tab, Shift+Tab, Enter, Space and Escape.\u003C\u002Fli>\u003Cli>Zoom to 200 percent and 400 percent. The menu must still be reachable.\u003C\u002Fli>\u003Cli>Test with a screen reader and check that the button state is announced as expanded or collapsed.\u003C\u002Fli>\u003Cli>Test on a real phone with one hand.\u003C\u002Fli>\u003Cli>Test at in-between widths, not only at phone and desktop sizes.\u003C\u002Fli>\u003Cli>Test with reduced motion enabled.\u003C\u002Fli>\u003C\u002Fol>\u003Ch2 id=\"11-common-mistakes\">11. Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Using a div or span as the menu button.\u003C\u002Fli>\u003Cli>Forgetting aria-expanded, or forgetting to update it.\u003C\u002Fli>\u003Cli>Hiding the menu only visually, for example with opacity 0 or off-screen positioning, so hidden links still receive focus.\u003C\u002Fli>\u003Cli>Hover-only dropdowns that cannot be opened with keyboard or touch.\u003C\u002Fli>\u003Cli>Using role='menu' for ordinary site navigation.\u003C\u002Fli>\u003Cli>No Escape key support and no focus return.\u003C\u002Fli>\u003Cli>Transitioning display none, which cannot animate. Animate transform and opacity and toggle visibility.\u003C\u002Fli>\u003Cli>Hamburger menus on desktop when all links fit.\u003C\u002Fli>\u003Cli>Removing the focus outline.\u003C\u002Fli>\u003Cli>Tiny tap targets placed very close together.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2 id=\"key-takeaways\">Key Takeaways\u003C\u002Fh2>\u003Cp>Start with semantic nav markup, write the small screen version first, use a real button with aria-expanded and aria-controls for the toggle, hide closed menus from the keyboard, support Escape and focus return, never rely on hover alone, keep touch targets large, and switch to a simple inline row when there is enough space.\u003C\u002Fp>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  .nav { background: #264653; padding: 10px 16px; }\n  .nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }\n  .nav a { color: #fff; text-decoration: none; display: inline-block; padding: 12px 14px; min-height: 44px; border-radius: 8px; }\n  .nav a:hover, .nav a:focus-visible { background: rgba(255,255,255,.18); }\n  .nav a:focus-visible { outline: 3px solid #ffb703; }\n  .nav a[aria-current='page'] { background: #e9c46a; color: #111; }\n  .nav .push { margin-left: auto; }\n&lt;\u002Fstyle&gt;\n&lt;nav class='nav' aria-label='Main'&gt;\n  &lt;ul&gt;\n    &lt;li&gt;&lt;a href='#' aria-current='page'&gt;Home&lt;\u002Fa&gt;&lt;\u002Fli&gt;\n    &lt;li&gt;&lt;a href='#'&gt;Courses&lt;\u002Fa&gt;&lt;\u002Fli&gt;\n    &lt;li&gt;&lt;a href='#'&gt;Blog&lt;\u002Fa&gt;&lt;\u002Fli&gt;\n    &lt;li class='push'&gt;&lt;a href='#'&gt;Sign in&lt;\u002Fa&gt;&lt;\u002Fli&gt;\n  &lt;\u002Ful&gt;\n&lt;\u002Fnav&gt;\n&lt;p style='padding:16px'&gt;Simplest pattern: flex-wrap handles small screens when there are only a few links.&lt;\u002Fp&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  .site { background: #264653; color: #fff; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; }\n  .logo { font-weight: 800; font-size: 20px; }\n  .menu-btn { background: transparent; color: #fff; border: 2px solid #fff; border-radius: 8px; padding: 8px 14px; min-height: 44px; font: inherit; cursor: pointer; }\n  .menu { display: none; width: 100%; }\n  .menu[data-open='true'] { display: block; }\n  .menu ul { list-style: none; margin: 8px 0 0; padding: 0; }\n  .menu a { display: block; color: #fff; text-decoration: none; padding: 12px 8px; min-height: 44px; border-top: 1px solid rgba(255,255,255,.2); }\n  .menu a:focus-visible, .menu-btn:focus-visible { outline: 3px solid #ffb703; outline-offset: 2px; }\n  @media (min-width: 768px) {\n    .menu-btn { display: none; }\n    .menu { display: block; width: auto; }\n    .menu ul { display: flex; gap: 4px; margin: 0; }\n    .menu a { border: 0; border-radius: 8px; padding: 10px 14px; }\n    .menu a:hover { background: rgba(255,255,255,.18); }\n  }\n&lt;\u002Fstyle&gt;\n&lt;header class='site'&gt;\n  &lt;a class='logo' href='#' style='color:#fff;text-decoration:none'&gt;Brand&lt;\u002Fa&gt;\n  &lt;button class='menu-btn' aria-expanded='false' aria-controls='menu'&gt;Menu&lt;\u002Fbutton&gt;\n  &lt;nav id='menu' class='menu' aria-label='Main' data-open='false'&gt;\n    &lt;ul&gt;&lt;li&gt;&lt;a href='#' aria-current='page'&gt;Home&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Courses&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Blog&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Contact&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;\u002Ful&gt;\n  &lt;\u002Fnav&gt;\n&lt;\u002Fheader&gt;\n&lt;p style='padding:16px'&gt;Narrow the preview below 768px to see the Menu button.&lt;\u002Fp&gt;\n&lt;script&gt;\n  var btn = document.querySelector('.menu-btn');\n  var menu = document.getElementById('menu');\n  function setOpen(open) {\n    btn.setAttribute('aria-expanded', String(open));\n    menu.setAttribute('data-open', String(open));\n  }\n  btn.addEventListener('click', function () { setOpen(btn.getAttribute('aria-expanded') !== 'true'); });\n  document.addEventListener('keydown', function (e) {\n    if (e.key === 'Escape' &amp;&amp; btn.getAttribute('aria-expanded') === 'true') { setOpen(false); btn.focus(); }\n  });\n&lt;\u002Fscript&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  body.locked { overflow: hidden; }\n  header { background: #264653; padding: 8px 16px; }\n  .open-btn { background: #e9c46a; border: 0; border-radius: 8px; padding: 10px 16px; min-height: 44px; font: inherit; cursor: pointer; }\n  .overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .25s; z-index: 200; }\n  .overlay.open { opacity: 1; pointer-events: auto; }\n  .drawer { position: fixed; inset: 0 auto 0 0; width: min(80vw, 300px); background: #1b2d36; color: #fff; padding: 16px; z-index: 300; transform: translateX(-100%); visibility: hidden; transition: transform .25s, visibility .25s; }\n  .drawer.open { transform: none; visibility: visible; }\n  .drawer ul { list-style: none; margin: 16px 0 0; padding: 0; }\n  .drawer a { display: block; color: #fff; text-decoration: none; padding: 12px 8px; min-height: 44px; border-bottom: 1px solid rgba(255,255,255,.15); }\n  .drawer a:focus-visible, .close:focus-visible { outline: 3px solid #ffb703; }\n  .close { background: none; border: 2px solid #fff; color: #fff; border-radius: 8px; padding: 6px 12px; min-height: 40px; cursor: pointer; font: inherit; }\n  @media (prefers-reduced-motion: reduce) { .overlay, .drawer { transition: none; } }\n&lt;\u002Fstyle&gt;\n&lt;header&gt;&lt;button class='open-btn' id='open' aria-expanded='false' aria-controls='drawer'&gt;Open menu&lt;\u002Fbutton&gt;&lt;\u002Fheader&gt;\n&lt;div class='overlay' id='overlay'&gt;&lt;\u002Fdiv&gt;\n&lt;nav class='drawer' id='drawer' aria-label='Main'&gt;\n  &lt;button class='close' id='close'&gt;Close&lt;\u002Fbutton&gt;\n  &lt;ul&gt;&lt;li&gt;&lt;a href='#'&gt;Home&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Courses&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Blog&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Contact&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;\u002Ful&gt;\n&lt;\u002Fnav&gt;\n&lt;main style='padding:16px'&gt;Page content. Open the drawer, press Escape or click the overlay to close it.&lt;\u002Fmain&gt;\n&lt;script&gt;\n  var openBtn = document.getElementById('open');\n  var drawer = document.getElementById('drawer');\n  var overlay = document.getElementById('overlay');\n  function openDrawer() {\n    drawer.classList.add('open'); overlay.classList.add('open');\n    document.body.classList.add('locked'); openBtn.setAttribute('aria-expanded', 'true');\n    drawer.querySelector('a').focus();\n  }\n  function closeDrawer() {\n    drawer.classList.remove('open'); overlay.classList.remove('open');\n    document.body.classList.remove('locked'); openBtn.setAttribute('aria-expanded', 'false');\n    openBtn.focus();\n  }\n  openBtn.addEventListener('click', openDrawer);\n  document.getElementById('close').addEventListener('click', closeDrawer);\n  overlay.addEventListener('click', closeDrawer);\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape' &amp;&amp; drawer.classList.contains('open')) { closeDrawer(); } });\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: 16px system-ui, sans-serif; }\n  .nav { background: #264653; padding: 8px 16px; display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap; }\n  .nav &gt; a, .nav summary { color: #fff; padding: 12px 14px; min-height: 44px; text-decoration: none; border-radius: 8px; cursor: pointer; display: block; list-style: none; }\n  .nav summary::-webkit-details-marker { display: none; }\n  .nav summary::after { content: ' \\25BE'; }\n  .nav a:hover, .nav summary:hover, .nav summary:focus-visible, .nav a:focus-visible { background: rgba(255,255,255,.18); outline: none; }\n  .nav details { position: relative; }\n  .nav details ul { position: absolute; top: 100%; left: 0; min-width: 180px; margin: 0; padding: 6px; list-style: none; background: #fff; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.25); z-index: 10; }\n  .nav details ul a { color: #1b1b1f; display: block; padding: 10px 12px; min-height: 44px; text-decoration: none; border-radius: 6px; }\n  .nav details ul a:hover, .nav details ul a:focus-visible { background: #eef2f7; }\n&lt;\u002Fstyle&gt;\n&lt;nav class='nav' aria-label='Main'&gt;\n  &lt;a href='#'&gt;Home&lt;\u002Fa&gt;\n  &lt;details&gt;\n    &lt;summary&gt;Courses&lt;\u002Fsummary&gt;\n    &lt;ul&gt;&lt;li&gt;&lt;a href='#'&gt;HTML&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;CSS&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;JavaScript&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;\u002Ful&gt;\n  &lt;\u002Fdetails&gt;\n  &lt;a href='#'&gt;Blog&lt;\u002Fa&gt;\n&lt;\u002Fnav&gt;\n&lt;p style='padding:16px'&gt;details and summary give a keyboard accessible dropdown with no JavaScript. Use Tab, Enter and Space.&lt;\u002Fp&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;style&gt;\n  body { margin: 0; font: 16px system-ui, sans-serif; min-height: 240px; }\n  .nav { background: #264653; padding: 8px 16px; display: flex; gap: 8px; }\n  .has-sub { position: relative; }\n  .has-sub &gt; button, .nav &gt; a { color: #fff; background: transparent; border: 0; font: inherit; padding: 12px 14px; min-height: 44px; border-radius: 8px; cursor: pointer; text-decoration: none; display: block; }\n  .has-sub &gt; button:focus-visible, .nav a:focus-visible { outline: 3px solid #ffb703; }\n  .sub { display: none; position: absolute; top: 100%; left: 0; min-width: 180px; padding: 6px; margin: 0; list-style: none; background: #fff; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.25); }\n  .sub a { display: block; color: #1b1b1f; text-decoration: none; padding: 10px 12px; min-height: 44px; border-radius: 6px; }\n  .sub a:hover, .sub a:focus-visible { background: #eef2f7; }\n  .has-sub.open .sub { display: block; }\n  @media (hover: hover) {\n    .has-sub:hover .sub { display: block; }\n  }\n  .has-sub:focus-within .sub { display: block; }\n&lt;\u002Fstyle&gt;\n&lt;nav class='nav' aria-label='Main'&gt;\n  &lt;a href='#'&gt;Home&lt;\u002Fa&gt;\n  &lt;div class='has-sub'&gt;\n    &lt;button aria-expanded='false' aria-controls='sub1'&gt;Products&lt;\u002Fbutton&gt;\n    &lt;ul class='sub' id='sub1'&gt;&lt;li&gt;&lt;a href='#'&gt;Laptops&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Phones&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;li&gt;&lt;a href='#'&gt;Accessories&lt;\u002Fa&gt;&lt;\u002Fli&gt;&lt;\u002Ful&gt;\n  &lt;\u002Fdiv&gt;\n  &lt;a href='#'&gt;Support&lt;\u002Fa&gt;\n&lt;\u002Fnav&gt;\n&lt;p style='padding:16px'&gt;The submenu opens with hover, keyboard focus and a click or tap on the button.&lt;\u002Fp&gt;\n&lt;script&gt;\n  var item = document.querySelector('.has-sub');\n  var trigger = item.querySelector('button');\n  trigger.addEventListener('click', function () {\n    var open = item.classList.toggle('open');\n    trigger.setAttribute('aria-expanded', String(open));\n  });\n  document.addEventListener('keydown', function (e) {\n    if (e.key === 'Escape') { item.classList.remove('open'); trigger.setAttribute('aria-expanded', 'false'); trigger.focus(); }\n  });\n&lt;\u002Fscript&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;meta name='viewport' content='width=device-width, initial-scale=1, viewport-fit=cover'&gt;\n&lt;style&gt;\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; padding-bottom: 88px; }\n  .tabs { position: fixed; inset: auto 0 0 0; display: flex; justify-content: space-around; background: #264653; padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px)); z-index: 100; }\n  .tabs a { flex: 1; color: #fff; text-decoration: none; text-align: center; padding: 8px 4px; min-height: 52px; border-radius: 10px; display: grid; gap: 2px; align-content: center; font-size: 13px; }\n  .tabs a span { font-size: 20px; line-height: 1; }\n  .tabs a[aria-current='page'] { background: #e9c46a; color: #111; }\n  .tabs a:focus-visible { outline: 3px solid #ffb703; }\n  @media (min-width: 768px) {\n    body { padding-bottom: 0; }\n    .tabs { position: static; justify-content: flex-start; gap: 6px; padding: 8px 16px; }\n    .tabs a { flex: 0 0 auto; grid-auto-flow: column; gap: 8px; font-size: 16px; padding: 8px 16px; min-height: 44px; }\n  }\n&lt;\u002Fstyle&gt;\n&lt;main style='padding:16px'&gt;&lt;h2&gt;Bottom tab bar&lt;\u002Fh2&gt;&lt;p&gt;Below 768px the bar is fixed at the bottom for thumb reach. From 768px it becomes a normal top navigation.&lt;\u002Fp&gt;&lt;\u002Fmain&gt;\n&lt;nav class='tabs' aria-label='Main'&gt;\n  &lt;a href='#' aria-current='page'&gt;&lt;span&gt;&amp;#8962;&lt;\u002Fspan&gt;Home&lt;\u002Fa&gt;\n  &lt;a href='#'&gt;&lt;span&gt;&amp;#9906;&lt;\u002Fspan&gt;Search&lt;\u002Fa&gt;\n  &lt;a href='#'&gt;&lt;span&gt;&amp;#9829;&lt;\u002Fspan&gt;Saved&lt;\u002Fa&gt;\n  &lt;a href='#'&gt;&lt;span&gt;&amp;#9786;&lt;\u002Fspan&gt;Profile&lt;\u002Fa&gt;\n&lt;\u002Fnav&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-javascript\">\u003Cpre>\u003Ccode>var state = { open: false };\n\nfunction toggle() {\n  state.open = !state.open;\n  return {\n    ariaExpanded: String(state.open),\n    menuHidden: !state.open,\n    focusTarget: state.open ? 'first link in the menu (drawer) or stay on button' : 'menu button'\n  };\n}\n\nfunction pressEscape() {\n  if (!state.open) { return 'Nothing to close'; }\n  state.open = false;\n  return 'Menu closed, focus returned to the menu button';\n}\n\nconsole.log('Click 1:', JSON.stringify(toggle()));\nconsole.log('Escape:', pressEscape());\nconsole.log('Click 2:', JSON.stringify(toggle()));\nconsole.log('Click 3:', JSON.stringify(toggle()));\n\nvar wide = window.matchMedia('(min-width: 768px)');\nconsole.log('Desktop layout active: ' + wide.matches + ' (reset the menu state when this changes)');\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>",{"name":9,"slug":10},{"name":611,"slug":612},{"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\u002Fresponsive-navigation-pattern","Responsive Navigation: Hamburger Menu, Off-Canvas, Dropdown, ARIA","Build an accessible responsive navigation: mobile-first nav, hamburger toggle with aria-expanded, off-canvas drawer, dropdowns, bottom tab bar, keyboard support and Escape.",[686,694,698,702,706,710,714,718,722,726,730,734,738],{"id":687,"text":688,"level":12,"children":689},"responsive-navigation-patterns-accessible-and-mobile-first","Responsive Navigation Patterns: Accessible and Mobile-First",[690],{"id":691,"text":692,"level":57,"children":693},"trending-keywords-covered-in-this-lesson","Trending keywords covered in this lesson",[],{"id":695,"text":696,"level":12,"children":697},"1-common-responsive-navigation-patterns","1. Common Responsive Navigation Patterns",[],{"id":699,"text":700,"level":12,"children":701},"2-semantic-html-first","2. Semantic HTML First",[],{"id":703,"text":704,"level":12,"children":705},"3-the-mobile-first-toggle-menu","3. The Mobile-First Toggle Menu",[],{"id":707,"text":708,"level":12,"children":709},"4-keyboard-and-focus-behavior","4. Keyboard and Focus Behavior",[],{"id":711,"text":712,"level":12,"children":713},"5-off-canvas-drawer","5. Off-Canvas Drawer",[],{"id":715,"text":716,"level":12,"children":717},"6-dropdown-submenus","6. Dropdown Submenus",[],{"id":719,"text":720,"level":12,"children":721},"7-bottom-tab-bar","7. Bottom Tab Bar",[],{"id":723,"text":724,"level":12,"children":725},"8-sticky-header","8. Sticky Header",[],{"id":727,"text":728,"level":12,"children":729},"9-touch-target-size-and-spacing","9. Touch Target Size and Spacing",[],{"id":731,"text":732,"level":12,"children":733},"10-test-your-navigation","10. Test Your Navigation",[],{"id":735,"text":736,"level":12,"children":737},"11-common-mistakes","11. Common Mistakes",[],{"id":739,"text":740,"level":12,"children":741},"key-takeaways","Key Takeaways",[],[743,747,750,753,756,759,762],{"id":744,"language":16,"code":745,"is_editable":746},565,"\u003Cstyle>\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  .nav { background: #264653; padding: 10px 16px; }\n  .nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }\n  .nav a { color: #fff; text-decoration: none; display: inline-block; padding: 12px 14px; min-height: 44px; border-radius: 8px; }\n  .nav a:hover, .nav a:focus-visible { background: rgba(255,255,255,.18); }\n  .nav a:focus-visible { outline: 3px solid #ffb703; }\n  .nav a[aria-current='page'] { background: #e9c46a; color: #111; }\n  .nav .push { margin-left: auto; }\n\u003C\u002Fstyle>\n\u003Cnav class='nav' aria-label='Main'>\n  \u003Cul>\n    \u003Cli>\u003Ca href='#' aria-current='page'>Home\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href='#'>Courses\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href='#'>Blog\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli class='push'>\u003Ca href='#'>Sign in\u003C\u002Fa>\u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fnav>\n\u003Cp style='padding:16px'>Simplest pattern: flex-wrap handles small screens when there are only a few links.\u003C\u002Fp>",true,{"id":748,"language":16,"code":749,"is_editable":746},566,"\u003Cstyle>\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  .site { background: #264653; color: #fff; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; }\n  .logo { font-weight: 800; font-size: 20px; }\n  .menu-btn { background: transparent; color: #fff; border: 2px solid #fff; border-radius: 8px; padding: 8px 14px; min-height: 44px; font: inherit; cursor: pointer; }\n  .menu { display: none; width: 100%; }\n  .menu[data-open='true'] { display: block; }\n  .menu ul { list-style: none; margin: 8px 0 0; padding: 0; }\n  .menu a { display: block; color: #fff; text-decoration: none; padding: 12px 8px; min-height: 44px; border-top: 1px solid rgba(255,255,255,.2); }\n  .menu a:focus-visible, .menu-btn:focus-visible { outline: 3px solid #ffb703; outline-offset: 2px; }\n  @media (min-width: 768px) {\n    .menu-btn { display: none; }\n    .menu { display: block; width: auto; }\n    .menu ul { display: flex; gap: 4px; margin: 0; }\n    .menu a { border: 0; border-radius: 8px; padding: 10px 14px; }\n    .menu a:hover { background: rgba(255,255,255,.18); }\n  }\n\u003C\u002Fstyle>\n\u003Cheader class='site'>\n  \u003Ca class='logo' href='#' style='color:#fff;text-decoration:none'>Brand\u003C\u002Fa>\n  \u003Cbutton class='menu-btn' aria-expanded='false' aria-controls='menu'>Menu\u003C\u002Fbutton>\n  \u003Cnav id='menu' class='menu' aria-label='Main' data-open='false'>\n    \u003Cul>\u003Cli>\u003Ca href='#' aria-current='page'>Home\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Courses\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Blog\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Contact\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\n  \u003C\u002Fnav>\n\u003C\u002Fheader>\n\u003Cp style='padding:16px'>Narrow the preview below 768px to see the Menu button.\u003C\u002Fp>\n\u003Cscript>\n  var btn = document.querySelector('.menu-btn');\n  var menu = document.getElementById('menu');\n  function setOpen(open) {\n    btn.setAttribute('aria-expanded', String(open));\n    menu.setAttribute('data-open', String(open));\n  }\n  btn.addEventListener('click', function () { setOpen(btn.getAttribute('aria-expanded') !== 'true'); });\n  document.addEventListener('keydown', function (e) {\n    if (e.key === 'Escape' && btn.getAttribute('aria-expanded') === 'true') { setOpen(false); btn.focus(); }\n  });\n\u003C\u002Fscript>",{"id":751,"language":16,"code":752,"is_editable":746},567,"\u003Cstyle>\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  body.locked { overflow: hidden; }\n  header { background: #264653; padding: 8px 16px; }\n  .open-btn { background: #e9c46a; border: 0; border-radius: 8px; padding: 10px 16px; min-height: 44px; font: inherit; cursor: pointer; }\n  .overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .25s; z-index: 200; }\n  .overlay.open { opacity: 1; pointer-events: auto; }\n  .drawer { position: fixed; inset: 0 auto 0 0; width: min(80vw, 300px); background: #1b2d36; color: #fff; padding: 16px; z-index: 300; transform: translateX(-100%); visibility: hidden; transition: transform .25s, visibility .25s; }\n  .drawer.open { transform: none; visibility: visible; }\n  .drawer ul { list-style: none; margin: 16px 0 0; padding: 0; }\n  .drawer a { display: block; color: #fff; text-decoration: none; padding: 12px 8px; min-height: 44px; border-bottom: 1px solid rgba(255,255,255,.15); }\n  .drawer a:focus-visible, .close:focus-visible { outline: 3px solid #ffb703; }\n  .close { background: none; border: 2px solid #fff; color: #fff; border-radius: 8px; padding: 6px 12px; min-height: 40px; cursor: pointer; font: inherit; }\n  @media (prefers-reduced-motion: reduce) { .overlay, .drawer { transition: none; } }\n\u003C\u002Fstyle>\n\u003Cheader>\u003Cbutton class='open-btn' id='open' aria-expanded='false' aria-controls='drawer'>Open menu\u003C\u002Fbutton>\u003C\u002Fheader>\n\u003Cdiv class='overlay' id='overlay'>\u003C\u002Fdiv>\n\u003Cnav class='drawer' id='drawer' aria-label='Main'>\n  \u003Cbutton class='close' id='close'>Close\u003C\u002Fbutton>\n  \u003Cul>\u003Cli>\u003Ca href='#'>Home\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Courses\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Blog\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Contact\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\n\u003C\u002Fnav>\n\u003Cmain style='padding:16px'>Page content. Open the drawer, press Escape or click the overlay to close it.\u003C\u002Fmain>\n\u003Cscript>\n  var openBtn = document.getElementById('open');\n  var drawer = document.getElementById('drawer');\n  var overlay = document.getElementById('overlay');\n  function openDrawer() {\n    drawer.classList.add('open'); overlay.classList.add('open');\n    document.body.classList.add('locked'); openBtn.setAttribute('aria-expanded', 'true');\n    drawer.querySelector('a').focus();\n  }\n  function closeDrawer() {\n    drawer.classList.remove('open'); overlay.classList.remove('open');\n    document.body.classList.remove('locked'); openBtn.setAttribute('aria-expanded', 'false');\n    openBtn.focus();\n  }\n  openBtn.addEventListener('click', openDrawer);\n  document.getElementById('close').addEventListener('click', closeDrawer);\n  overlay.addEventListener('click', closeDrawer);\n  document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && drawer.classList.contains('open')) { closeDrawer(); } });\n\u003C\u002Fscript>",{"id":754,"language":16,"code":755,"is_editable":746},568,"\u003Cstyle>\n  body { margin: 0; font: 16px system-ui, sans-serif; }\n  .nav { background: #264653; padding: 8px 16px; display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap; }\n  .nav > a, .nav summary { color: #fff; padding: 12px 14px; min-height: 44px; text-decoration: none; border-radius: 8px; cursor: pointer; display: block; list-style: none; }\n  .nav summary::-webkit-details-marker { display: none; }\n  .nav summary::after { content: ' \\25BE'; }\n  .nav a:hover, .nav summary:hover, .nav summary:focus-visible, .nav a:focus-visible { background: rgba(255,255,255,.18); outline: none; }\n  .nav details { position: relative; }\n  .nav details ul { position: absolute; top: 100%; left: 0; min-width: 180px; margin: 0; padding: 6px; list-style: none; background: #fff; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.25); z-index: 10; }\n  .nav details ul a { color: #1b1b1f; display: block; padding: 10px 12px; min-height: 44px; text-decoration: none; border-radius: 6px; }\n  .nav details ul a:hover, .nav details ul a:focus-visible { background: #eef2f7; }\n\u003C\u002Fstyle>\n\u003Cnav class='nav' aria-label='Main'>\n  \u003Ca href='#'>Home\u003C\u002Fa>\n  \u003Cdetails>\n    \u003Csummary>Courses\u003C\u002Fsummary>\n    \u003Cul>\u003Cli>\u003Ca href='#'>HTML\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>CSS\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>JavaScript\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\n  \u003C\u002Fdetails>\n  \u003Ca href='#'>Blog\u003C\u002Fa>\n\u003C\u002Fnav>\n\u003Cp style='padding:16px'>details and summary give a keyboard accessible dropdown with no JavaScript. Use Tab, Enter and Space.\u003C\u002Fp>",{"id":757,"language":16,"code":758,"is_editable":746},569,"\u003Cstyle>\n  body { margin: 0; font: 16px system-ui, sans-serif; min-height: 240px; }\n  .nav { background: #264653; padding: 8px 16px; display: flex; gap: 8px; }\n  .has-sub { position: relative; }\n  .has-sub > button, .nav > a { color: #fff; background: transparent; border: 0; font: inherit; padding: 12px 14px; min-height: 44px; border-radius: 8px; cursor: pointer; text-decoration: none; display: block; }\n  .has-sub > button:focus-visible, .nav a:focus-visible { outline: 3px solid #ffb703; }\n  .sub { display: none; position: absolute; top: 100%; left: 0; min-width: 180px; padding: 6px; margin: 0; list-style: none; background: #fff; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.25); }\n  .sub a { display: block; color: #1b1b1f; text-decoration: none; padding: 10px 12px; min-height: 44px; border-radius: 6px; }\n  .sub a:hover, .sub a:focus-visible { background: #eef2f7; }\n  .has-sub.open .sub { display: block; }\n  @media (hover: hover) {\n    .has-sub:hover .sub { display: block; }\n  }\n  .has-sub:focus-within .sub { display: block; }\n\u003C\u002Fstyle>\n\u003Cnav class='nav' aria-label='Main'>\n  \u003Ca href='#'>Home\u003C\u002Fa>\n  \u003Cdiv class='has-sub'>\n    \u003Cbutton aria-expanded='false' aria-controls='sub1'>Products\u003C\u002Fbutton>\n    \u003Cul class='sub' id='sub1'>\u003Cli>\u003Ca href='#'>Laptops\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Phones\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Accessories\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\n  \u003C\u002Fdiv>\n  \u003Ca href='#'>Support\u003C\u002Fa>\n\u003C\u002Fnav>\n\u003Cp style='padding:16px'>The submenu opens with hover, keyboard focus and a click or tap on the button.\u003C\u002Fp>\n\u003Cscript>\n  var item = document.querySelector('.has-sub');\n  var trigger = item.querySelector('button');\n  trigger.addEventListener('click', function () {\n    var open = item.classList.toggle('open');\n    trigger.setAttribute('aria-expanded', String(open));\n  });\n  document.addEventListener('keydown', function (e) {\n    if (e.key === 'Escape') { item.classList.remove('open'); trigger.setAttribute('aria-expanded', 'false'); trigger.focus(); }\n  });\n\u003C\u002Fscript>",{"id":760,"language":16,"code":761,"is_editable":746},570,"\u003Cmeta name='viewport' content='width=device-width, initial-scale=1, viewport-fit=cover'>\n\u003Cstyle>\n  *, *::before, *::after { box-sizing: border-box; }\n  body { margin: 0; font: 16px system-ui, sans-serif; padding-bottom: 88px; }\n  .tabs { position: fixed; inset: auto 0 0 0; display: flex; justify-content: space-around; background: #264653; padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px)); z-index: 100; }\n  .tabs a { flex: 1; color: #fff; text-decoration: none; text-align: center; padding: 8px 4px; min-height: 52px; border-radius: 10px; display: grid; gap: 2px; align-content: center; font-size: 13px; }\n  .tabs a span { font-size: 20px; line-height: 1; }\n  .tabs a[aria-current='page'] { background: #e9c46a; color: #111; }\n  .tabs a:focus-visible { outline: 3px solid #ffb703; }\n  @media (min-width: 768px) {\n    body { padding-bottom: 0; }\n    .tabs { position: static; justify-content: flex-start; gap: 6px; padding: 8px 16px; }\n    .tabs a { flex: 0 0 auto; grid-auto-flow: column; gap: 8px; font-size: 16px; padding: 8px 16px; min-height: 44px; }\n  }\n\u003C\u002Fstyle>\n\u003Cmain style='padding:16px'>\u003Ch2>Bottom tab bar\u003C\u002Fh2>\u003Cp>Below 768px the bar is fixed at the bottom for thumb reach. From 768px it becomes a normal top navigation.\u003C\u002Fp>\u003C\u002Fmain>\n\u003Cnav class='tabs' aria-label='Main'>\n  \u003Ca href='#' aria-current='page'>\u003Cspan>&#8962;\u003C\u002Fspan>Home\u003C\u002Fa>\n  \u003Ca href='#'>\u003Cspan>&#9906;\u003C\u002Fspan>Search\u003C\u002Fa>\n  \u003Ca href='#'>\u003Cspan>&#9829;\u003C\u002Fspan>Saved\u003C\u002Fa>\n  \u003Ca href='#'>\u003Cspan>&#9786;\u003C\u002Fspan>Profile\u003C\u002Fa>\n\u003C\u002Fnav>",{"id":763,"language":764,"code":765,"is_editable":746},571,"javascript","var state = { open: false };\n\nfunction toggle() {\n  state.open = !state.open;\n  return {\n    ariaExpanded: String(state.open),\n    menuHidden: !state.open,\n    focusTarget: state.open ? 'first link in the menu (drawer) or stay on button' : 'menu button'\n  };\n}\n\nfunction pressEscape() {\n  if (!state.open) { return 'Nothing to close'; }\n  state.open = false;\n  return 'Menu closed, focus returned to the menu button';\n}\n\nconsole.log('Click 1:', JSON.stringify(toggle()));\nconsole.log('Escape:', pressEscape());\nconsole.log('Click 2:', JSON.stringify(toggle()));\nconsole.log('Click 3:', JSON.stringify(toggle()));\n\nvar wide = window.matchMedia('(min-width: 768px)');\nconsole.log('Desktop layout active: ' + wide.matches + ' (reset the menu state when this changes)');",[767,774],{"id":768,"title":769,"slug":770,"prompt":771,"starter_code":772,"expected_output":773,"language":16,"order_index":23},203,"Make a Navigation Responsive with a Menu Button","responsive-nav-with-menu-button","Turn the inline navigation into a mobile-first responsive menu. Below 768px show a Menu button with aria-expanded and aria-controls and hide the links. From 768px hide the button and show the links in a row. Use a data attribute or a class to open the menu, and write the small screen styles as the base.","\u003Cstyle>\n  nav { background: #264653; padding: 10px; }\n  nav ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 12px; }\n  nav a { color: #fff; text-decoration: none; padding: 10px; display: block; }\n\u003C\u002Fstyle>\n\u003Cnav aria-label='Main'>\n  \u003Cul>\u003Cli>\u003Ca href='#'>Home\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>About\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Contact\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\n\u003C\u002Fnav>","A button with aria-expanded and aria-controls, menu hidden by default, toggled by JavaScript, and a @media (min-width: 768px) rule that hides the button and displays the links as a row",{"id":775,"title":776,"slug":777,"prompt":778,"starter_code":779,"expected_output":780,"language":16,"order_index":12},204,"Add Escape Key and Focus Return","add-escape-key-and-focus-return","The menu button toggles the menu, but it is missing keyboard support. Add code so that pressing Escape closes the open menu, updates aria-expanded to false and returns focus to the button. Also make sure the hidden menu cannot be reached with the Tab key.","\u003Cstyle>\n  .menu { display: none; }\n  .menu.open { display: block; }\n\u003C\u002Fstyle>\n\u003Cbutton id='btn' aria-expanded='false' aria-controls='menu'>Menu\u003C\u002Fbutton>\n\u003Cnav id='menu' class='menu' aria-label='Main'>\u003Cul>\u003Cli>\u003Ca href='#'>Home\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca href='#'>Docs\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fnav>\n\u003Cscript>\n  var btn = document.getElementById('btn');\n  var menu = document.getElementById('menu');\n  btn.addEventListener('click', function () {\n    var open = menu.classList.toggle('open');\n    btn.setAttribute('aria-expanded', String(open));\n  });\n\u003C\u002Fscript>","A keydown listener that checks for Escape, removes the open class, sets aria-expanded to false and calls btn.focus(), while the closed menu uses display: none so links are not focusable","2026-09-30T18:35:36+00:00",{"id":631,"slug":633,"title":632},{"id":643,"slug":645,"title":644}]