[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-config":3,"blog-categories":6,"course-tree":35,"topic:web-fonts":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":531,"title":532,"slug":533,"content":672,"course":673,"subcategory":674,"author":675,"reading_time_minutes":77,"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":745,"quiz":5,"exercises":769,"published_at":5,"updated_at":788,"prev":789,"next":790},"\u003Ch2 id=\"web-fonts-google-fonts-at-font-face-and-variable-fonts\">Web Fonts: Google Fonts, @font-face and Variable Fonts\u003C\u002Fh2>\u003Cp>\u003Cstrong>Web fonts\u003C\u002Fstrong> let you use any typeface on your site by downloading font files to the visitor browser. They give you consistent branding on every device, but they also cost bandwidth and can cause flashes of unstyled text and layout shift. This lesson shows how to use Google Fonts, write your own \u003Ccode>@font-face\u003C\u002Fcode>, choose formats, control loading with \u003Ccode>font-display\u003C\u002Fcode>, and use variable fonts.\u003C\u002Fp>\u003Ch3 id=\"what-you-will-learn\">What You Will Learn\u003C\u002Fh3>\u003Cul>\u003Cli>How to add Google Fonts with \u003Ccode>link\u003C\u002Fcode> and with \u003Ccode>@import\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>How to write \u003Ccode>@font-face\u003C\u002Fcode> rules and self-host fonts\u003C\u002Fli>\u003Cli>Font formats: WOFF2 and why it is enough today\u003C\u002Fli>\u003Cli>Loading behavior: FOIT, FOUT and \u003Ccode>font-display\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>Preloading, subsetting and \u003Ccode>unicode-range\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>Variable fonts: axes, \u003Ccode>font-variation-settings\u003C\u002Fcode> and weight ranges\u003C\u002Fli>\u003Cli>Performance, privacy and licensing\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"using-google-fonts\">Using Google Fonts\u003C\u002Fh3>\u003Cp>Choose a font on Google Fonts, pick the styles you need, and copy the embed code. The recommended pattern uses \u003Ccode>preconnect\u003C\u002Fcode> hints and a \u003Ccode>link\u003C\u002Fcode> tag in the \u003Ccode>head\u003C\u002Fcode>:\u003C\u002Fp>\u003Cpre>&lt;link rel='preconnect' href='https:\u002F\u002Ffonts.googleapis.com'&gt;\n&lt;link rel='preconnect' href='https:\u002F\u002Ffonts.gstatic.com' crossorigin&gt;\n&lt;link href='https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;600;700&amp;display=swap' rel='stylesheet'&gt;\u003C\u002Fpre>\u003Cp>Then use the font in CSS with a fallback: \u003Ccode>font-family: 'Inter', system-ui, sans-serif;\u003C\u002Fcode>. The \u003Ccode>display=swap\u003C\u002Fcode> parameter adds \u003Ccode>font-display: swap\u003C\u002Fcode> to the generated rules. Prefer the \u003Ccode>link\u003C\u002Fcode> method over \u003Ccode>@import\u003C\u002Fcode>, because \u003Ccode>@import\u003C\u002Fcode> inside CSS delays the download.\u003C\u002Fp>\u003Ch3 id=\"writing-at-font-face\">Writing @font-face\u003C\u002Fh3>\u003Cp>The \u003Ccode>@font-face\u003C\u002Fcode> at-rule declares a font family name and tells the browser where to get the file:\u003C\u002Fp>\u003Cpre>@font-face {\n  font-family: 'Inter';\n  src: url('\u002Ffonts\u002Finter-400.woff2') format('woff2');\n  font-weight: 400;\n  font-style: normal;\n  font-display: swap;\n}\u003C\u002Fpre>\u003Cul>\u003Cli>\u003Ccode>font-family\u003C\u002Fcode>: the name you will use in your CSS. It can be anything, but use a clear name.\u003C\u002Fli>\u003Cli>\u003Ccode>src\u003C\u002Fcode>: one or more sources. \u003Ccode>local()\u003C\u002Fcode> tries an installed copy first, \u003Ccode>url()\u003C\u002Fcode> downloads the file.\u003C\u002Fli>\u003Cli>\u003Ccode>font-weight\u003C\u002Fcode> and \u003Ccode>font-style\u003C\u002Fcode>: tell the browser which face this file is. Declare one rule per weight and style you use.\u003C\u002Fli>\u003Cli>\u003Ccode>font-display\u003C\u002Fcode>: controls what happens while the font loads.\u003C\u002Fli>\u003Cli>\u003Ccode>unicode-range\u003C\u002Fcode>: download this file only when the page uses characters in the range.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"font-formats\">Font Formats\u003C\u002Fh3>\u003Cul>\u003Cli>\u003Cstrong>WOFF2\u003C\u002Fstrong>: compressed, supported by all modern browsers. This is the only format you need for new projects.\u003C\u002Fli>\u003Cli>\u003Cstrong>WOFF\u003C\u002Fstrong>: older compressed format, needed only for very old browsers.\u003C\u002Fli>\u003Cli>\u003Cstrong>TTF\u002FOTF\u003C\u002Fstrong>: desktop formats, larger files. Convert them to WOFF2.\u003C\u002Fli>\u003Cli>\u003Cstrong>EOT\u003C\u002Fstrong> and \u003Cstrong>SVG\u003C\u002Fstrong> fonts: obsolete. Do not use them.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"font-loading-behavior-foit-and-fout\">Font Loading Behavior: FOIT and FOUT\u003C\u002Fh3>\u003Cul>\u003Cli>\u003Cstrong>FOIT\u003C\u002Fstrong> (flash of invisible text): text is hidden until the font arrives.\u003C\u002Fli>\u003Cli>\u003Cstrong>FOUT\u003C\u002Fstrong> (flash of unstyled text): text shows immediately in a fallback and swaps when the web font arrives.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>The \u003Ccode>font-display\u003C\u002Fcode> descriptor picks the behavior:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode>auto\u003C\u002Fcode>: browser default (usually like block).\u003C\u002Fli>\u003Cli>\u003Ccode>block\u003C\u002Fcode>: short invisible period, then swap. Use for icon fonts.\u003C\u002Fli>\u003Cli>\u003Ccode>swap\u003C\u002Fcode>: show fallback immediately, swap when ready. Best for body text and most sites.\u003C\u002Fli>\u003Cli>\u003Ccode>fallback\u003C\u002Fcode>: very short invisible period and a short swap window. Good balance to reduce visible shifts.\u003C\u002Fli>\u003Cli>\u003Ccode>optional\u003C\u002Fcode>: the font is used only if it loads very quickly, otherwise the fallback stays for that visit. Best for performance and no layout shift.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"preloading-critical-fonts\">Preloading Critical Fonts\u003C\u002Fh3>\u003Cp>Fonts are discovered late because the browser must first download CSS. Preload the one or two fonts used above the fold:\u003C\u002Fp>\u003Cpre>&lt;link rel='preload' href='\u002Ffonts\u002Finter-400.woff2' as='font' type='font\u002Fwoff2' crossorigin&gt;\u003C\u002Fpre>\u003Cp>The \u003Ccode>crossorigin\u003C\u002Fcode> attribute is required even for same-origin fonts. Preload only what you really need, since unused preloads waste bandwidth.\u003C\u002Fp>\u003Ch3 id=\"subsetting-and-unicode-range\">Subsetting and unicode-range\u003C\u002Fh3>\u003Cp>A font file may contain thousands of glyphs. You can subset it to only the languages you need, for example Latin only. Google Fonts does this automatically with several \u003Ccode>@font-face\u003C\u002Fcode> rules and \u003Ccode>unicode-range\u003C\u002Fcode> values, so a visitor downloads only the subset their page uses. For Urdu or Arabic pages, make sure the Arabic subset is included.\u003C\u002Fp>\u003Ch3 id=\"variable-fonts\">Variable Fonts\u003C\u002Fh3>\u003Cp>A \u003Cstrong>variable font\u003C\u002Fstrong> packs a whole family into one file with continuous axes. Registered axes are weight (\u003Ccode>wght\u003C\u002Fcode>), width (\u003Ccode>wdth\u003C\u002Fcode>), slant (\u003Ccode>slnt\u003C\u002Fcode>), italic (\u003Ccode>ital\u003C\u002Fcode>) and optical size (\u003Ccode>opsz\u003C\u002Fcode>). Fonts can also define custom axes in uppercase.\u003C\u002Fp>\u003Cpre>@font-face {\n  font-family: 'Inter VF';\n  src: url('\u002Ffonts\u002Finter-variable.woff2') format('woff2-variations');\n  font-weight: 100 900;\n  font-display: swap;\n}\nh1 { font-weight: 850; }\n.narrow { font-variation-settings: 'wdth' 80; }\u003C\u002Fpre>\u003Cul>\u003Cli>Declare the range with \u003Ccode>font-weight: 100 900\u003C\u002Fcode> so any number in that range works.\u003C\u002Fli>\u003Cli>Use the normal properties when they exist: \u003Ccode>font-weight\u003C\u002Fcode> for \u003Ccode>wght\u003C\u002Fcode>, \u003Ccode>font-stretch\u003C\u002Fcode> for \u003Ccode>wdth\u003C\u002Fcode>, \u003Ccode>font-style: oblique 10deg\u003C\u002Fcode> for \u003Ccode>slnt\u003C\u002Fcode>, and \u003Ccode>font-optical-sizing: auto\u003C\u002Fcode> for \u003Ccode>opsz\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Use \u003Ccode>font-variation-settings\u003C\u002Fcode> only for custom axes, and remember it overrides everything at once, so avoid mixing it with the standard properties.\u003C\u002Fli>\u003Cli>A single variable file is often smaller than three or four static weights, and it enables smooth animation of weight.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"reducing-layout-shift-with-fallback-metrics\">Reducing Layout Shift with Fallback Metrics\u003C\u002Fh3>\u003Cp>You can create a local fallback face that matches the web font metrics, so the swap causes almost no shift:\u003C\u002Fp>\u003Cpre>@font-face {\n  font-family: 'Inter Fallback';\n  src: local('Arial');\n  size-adjust: 107%;\n  ascent-override: 90%;\n  descent-override: 22%;\n  line-gap-override: 0%;\n}\nbody { font-family: 'Inter', 'Inter Fallback', sans-serif; }\u003C\u002Fpre>\u003Cp>Tools and frameworks can calculate these numbers for you. Modern build tools often generate them automatically.\u003C\u002Fp>\u003Ch3 id=\"the-css-font-loading-api\">The CSS Font Loading API\u003C\u002Fh3>\u003Cp>In JavaScript, \u003Ccode>document.fonts.load('1rem Inter')\u003C\u002Fcode> returns a promise, and \u003Ccode>document.fonts.ready\u003C\u002Fcode> resolves when all fonts used are loaded. You can use it to add a class like \u003Ccode>fonts-loaded\u003C\u002Fcode> to the \u003Ccode>html\u003C\u002Fcode> element.\u003C\u002Fp>\u003Ch3 id=\"performance-privacy-and-licensing\">Performance, Privacy and Licensing\u003C\u002Fh3>\u003Cul>\u003Cli>Limit families and weights. Every extra file costs time.\u003C\u002Fli>\u003Cli>Self-hosting (download the files and serve them yourself) removes third-party requests, gives you full caching control and avoids sending visitor IP addresses to an external font service. This matters for privacy rules such as GDPR.\u003C\u002Fli>\u003Cli>Check the license. Google Fonts are open source, but commercial fonts need a web license.\u003C\u002Fli>\u003Cli>Serve fonts with long cache headers, for example \u003Ccode>Cache-Control: public, max-age=31536000, immutable\u003C\u002Fcode>.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"common-mistakes\">Common Mistakes\u003C\u002Fh3>\u003Cul>\u003Cli>Loading six weights when the design uses two.\u003C\u002Fli>\u003Cli>Forgetting \u003Ccode>font-display\u003C\u002Fcode> and leaving text invisible on slow connections.\u003C\u002Fli>\u003Cli>Declaring a variable font without a weight range, so only one weight works.\u003C\u002Fli>\u003Cli>Missing \u003Ccode>crossorigin\u003C\u002Fcode> on a font preload, which makes the browser download the file twice.\u003C\u002Fli>\u003Cli>Using \u003Ccode>@import\u003C\u002Fcode> for Google Fonts inside a large CSS file.\u003C\u002Fli>\u003Cli>Skipping a fallback stack and generic family.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3 id=\"frequently-asked-questions\">Frequently Asked Questions\u003C\u002Fh3>\u003Ch4 id=\"which-font-format-should-i-use\">Which font format should I use?\u003C\u002Fh4>\u003Cp>WOFF2 only. It is supported by every current browser and has the best compression.\u003C\u002Fp>\u003Ch4 id=\"what-does-font-display-swap-do\">What does font-display: swap do?\u003C\u002Fh4>\u003Cp>It shows text immediately in a fallback font and replaces it with the web font when it finishes loading.\u003C\u002Fp>\u003Ch4 id=\"should-i-self-host-google-fonts\">Should I self-host Google Fonts?\u003C\u002Fh4>\u003Cp>Often yes. It improves control over caching and performance and avoids third-party requests, but you must update the files yourself.\u003C\u002Fp>\u003Ch4 id=\"what-is-a-variable-font\">What is a variable font?\u003C\u002Fh4>\u003Cp>A single font file that contains a range of styles, such as every weight from 100 to 900, which you select with normal CSS properties.\u003C\u002Fp>\u003Ch3 id=\"key-takeaways\">Key Takeaways\u003C\u002Fh3>\u003Cul>\u003Cli>Use WOFF2 with \u003Ccode>@font-face\u003C\u002Fcode> or the Google Fonts \u003Ccode>link\u003C\u002Fcode> with \u003Ccode>display=swap\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Always include a fallback stack and set \u003Ccode>font-display\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Preload only critical fonts and add \u003Ccode>crossorigin\u003C\u002Fcode>.\u003C\u002Fli>\u003Cli>Variable fonts reduce file count and give fine control through \u003Ccode>font-weight\u003C\u002Fcode> ranges.\u003C\u002Fli>\u003Cli>Match fallback metrics to reduce layout shift.\u003C\u002Fli>\u003C\u002Ful>\u003Cdiv class=\"try-it-yourself language-css\">\u003Cpre>\u003Ccode>\u002F* Self-hosted @font-face with WOFF2 *\u002F\n@font-face {\n  font-family: 'Inter';\n  src: local('Inter Regular'),\n       url('\u002Ffonts\u002Finter-400.woff2') format('woff2');\n  font-weight: 400;\n  font-style: normal;\n  font-display: swap;\n}\n@font-face {\n  font-family: 'Inter';\n  src: url('\u002Ffonts\u002Finter-700.woff2') format('woff2');\n  font-weight: 700;\n  font-style: normal;\n  font-display: swap;\n}\n\nbody {\n  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;!-- Put this inside &lt;head&gt; --&gt;\n&lt;link rel='preconnect' href='https:\u002F\u002Ffonts.googleapis.com'&gt;\n&lt;link rel='preconnect' href='https:\u002F\u002Ffonts.gstatic.com' crossorigin&gt;\n&lt;link href='https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;600;700&amp;display=swap' rel='stylesheet'&gt;\n\n&lt;style&gt;\n  body { font-family: 'Inter', system-ui, sans-serif; }\n  h1 { font-weight: 700; }\n&lt;\u002Fstyle&gt;\n&lt;h1&gt;Google Fonts heading&lt;\u002Fh1&gt;\n&lt;p&gt;Body text in Inter (falls back to the system font if the request fails).&lt;\u002Fp&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-html\">\u003Cpre>\u003Ccode>&lt;!-- Preload the critical font (note crossorigin is required) --&gt;\n&lt;link rel='preload' href='\u002Ffonts\u002Finter-400.woff2' as='font' type='font\u002Fwoff2' crossorigin&gt;\n\n&lt;style&gt;\n@font-face {\n  font-family: 'Inter';\n  src: url('\u002Ffonts\u002Finter-400.woff2') format('woff2');\n  font-weight: 400;\n  font-display: optional; \u002F* no layout shift: fallback stays if the font is slow *\u002F\n}\n&lt;\u002Fstyle&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-css\">\u003Cpre>\u003Ccode>\u002F* Variable font: one file, weight range 100-900 *\u002F\n@font-face {\n  font-family: 'Inter VF';\n  src: url('\u002Ffonts\u002Finter-variable.woff2') format('woff2-variations');\n  font-weight: 100 900;\n  font-stretch: 75% 125%;\n  font-display: swap;\n}\n\nh1   { font-family: 'Inter VF', sans-serif; font-weight: 850; }\n.lite { font-weight: 300; }\n.wide { font-stretch: 120%; }\n.custom { font-variation-settings: 'wght' 620, 'opsz' 28; }\n\n\u002F* Smooth weight animation on hover *\u002F\n.link { font-weight: 400; transition: font-weight 0.25s ease; }\n.link:hover { font-weight: 700; }\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-css\">\u003Cpre>\u003Ccode>\u002F* Fallback font tuned to match the web font metrics *\u002F\n@font-face {\n  font-family: 'Inter Fallback';\n  src: local('Arial');\n  size-adjust: 107%;\n  ascent-override: 90%;\n  descent-override: 22%;\n  line-gap-override: 0%;\n}\nbody {\n  font-family: 'Inter', 'Inter Fallback', sans-serif;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-css\">\u003Cpre>\u003Ccode>\u002F* unicode-range: download this file only when Latin characters are used *\u002F\n@font-face {\n  font-family: 'MyFont';\n  src: url('\u002Ffonts\u002Fmyfont-latin.woff2') format('woff2');\n  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;\n  font-display: swap;\n}\n\u002F* Arabic script subset (Urdu, Arabic) loads only when needed *\u002F\n@font-face {\n  font-family: 'MyFont';\n  src: url('\u002Ffonts\u002Fmyfont-arabic.woff2') format('woff2');\n  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFF;\n  font-display: swap;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\u003Cdiv class=\"try-it-yourself language-javascript\">\u003Cpre>\u003Ccode>\u002F\u002F Load a font with the CSS Font Loading API\nconst font = new FontFace('Inter', \"url('\u002Ffonts\u002Finter-400.woff2') format('woff2')\", { weight: '400', display: 'swap' });\n\nfont.load().then(loaded =&gt; {\n  document.fonts.add(loaded);\n  document.documentElement.classList.add('fonts-loaded');\n  console.log('Font loaded:', loaded.family);\n}).catch(err =&gt; console.log('Font failed, fallback stays:', err.message));\n\ndocument.fonts.ready.then(() =&gt; console.log('All fonts ready, count:', document.fonts.size));\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>",{"name":9,"slug":10},{"name":519,"slug":520},{"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\u002Fweb-fonts","Web Fonts Guide: Google Fonts, @font-face, WOFF2, Variable Fonts","Master web fonts: Google Fonts setup, @font-face, WOFF2, font-display, preload, unicode-range, variable fonts, fallback metrics, performance and privacy.",[686],{"id":687,"text":532,"level":12,"children":688},"web-fonts-google-fonts-at-font-face-and-variable-fonts",[689,693,697,701,705,709,713,717,721,725,729,733,737,741],{"id":690,"text":691,"level":57,"children":692},"what-you-will-learn","What You Will Learn",[],{"id":694,"text":695,"level":57,"children":696},"using-google-fonts","Using Google Fonts",[],{"id":698,"text":699,"level":57,"children":700},"writing-at-font-face","Writing @font-face",[],{"id":702,"text":703,"level":57,"children":704},"font-formats","Font Formats",[],{"id":706,"text":707,"level":57,"children":708},"font-loading-behavior-foit-and-fout","Font Loading Behavior: FOIT and FOUT",[],{"id":710,"text":711,"level":57,"children":712},"preloading-critical-fonts","Preloading Critical Fonts",[],{"id":714,"text":715,"level":57,"children":716},"subsetting-and-unicode-range","Subsetting and unicode-range",[],{"id":718,"text":719,"level":57,"children":720},"variable-fonts","Variable Fonts",[],{"id":722,"text":723,"level":57,"children":724},"reducing-layout-shift-with-fallback-metrics","Reducing Layout Shift with Fallback Metrics",[],{"id":726,"text":727,"level":57,"children":728},"the-css-font-loading-api","The CSS Font Loading API",[],{"id":730,"text":731,"level":57,"children":732},"performance-privacy-and-licensing","Performance, Privacy and Licensing",[],{"id":734,"text":735,"level":57,"children":736},"common-mistakes","Common Mistakes",[],{"id":738,"text":739,"level":57,"children":740},"frequently-asked-questions","Frequently Asked Questions",[],{"id":742,"text":743,"level":57,"children":744},"key-takeaways","Key Takeaways",[],[746,750,753,756,759,762,765],{"id":747,"language":10,"code":748,"is_editable":749},361,"\u002F* Self-hosted @font-face with WOFF2 *\u002F\n@font-face {\n  font-family: 'Inter';\n  src: local('Inter Regular'),\n       url('\u002Ffonts\u002Finter-400.woff2') format('woff2');\n  font-weight: 400;\n  font-style: normal;\n  font-display: swap;\n}\n@font-face {\n  font-family: 'Inter';\n  src: url('\u002Ffonts\u002Finter-700.woff2') format('woff2');\n  font-weight: 700;\n  font-style: normal;\n  font-display: swap;\n}\n\nbody {\n  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n}",true,{"id":751,"language":16,"code":752,"is_editable":749},362,"\u003C!-- Put this inside \u003Chead> -->\n\u003Clink rel='preconnect' href='https:\u002F\u002Ffonts.googleapis.com'>\n\u003Clink rel='preconnect' href='https:\u002F\u002Ffonts.gstatic.com' crossorigin>\n\u003Clink href='https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;600;700&display=swap' rel='stylesheet'>\n\n\u003Cstyle>\n  body { font-family: 'Inter', system-ui, sans-serif; }\n  h1 { font-weight: 700; }\n\u003C\u002Fstyle>\n\u003Ch1>Google Fonts heading\u003C\u002Fh1>\n\u003Cp>Body text in Inter (falls back to the system font if the request fails).\u003C\u002Fp>",{"id":754,"language":16,"code":755,"is_editable":749},363,"\u003C!-- Preload the critical font (note crossorigin is required) -->\n\u003Clink rel='preload' href='\u002Ffonts\u002Finter-400.woff2' as='font' type='font\u002Fwoff2' crossorigin>\n\n\u003Cstyle>\n@font-face {\n  font-family: 'Inter';\n  src: url('\u002Ffonts\u002Finter-400.woff2') format('woff2');\n  font-weight: 400;\n  font-display: optional; \u002F* no layout shift: fallback stays if the font is slow *\u002F\n}\n\u003C\u002Fstyle>",{"id":757,"language":10,"code":758,"is_editable":749},364,"\u002F* Variable font: one file, weight range 100-900 *\u002F\n@font-face {\n  font-family: 'Inter VF';\n  src: url('\u002Ffonts\u002Finter-variable.woff2') format('woff2-variations');\n  font-weight: 100 900;\n  font-stretch: 75% 125%;\n  font-display: swap;\n}\n\nh1   { font-family: 'Inter VF', sans-serif; font-weight: 850; }\n.lite { font-weight: 300; }\n.wide { font-stretch: 120%; }\n.custom { font-variation-settings: 'wght' 620, 'opsz' 28; }\n\n\u002F* Smooth weight animation on hover *\u002F\n.link { font-weight: 400; transition: font-weight 0.25s ease; }\n.link:hover { font-weight: 700; }",{"id":760,"language":10,"code":761,"is_editable":749},365,"\u002F* Fallback font tuned to match the web font metrics *\u002F\n@font-face {\n  font-family: 'Inter Fallback';\n  src: local('Arial');\n  size-adjust: 107%;\n  ascent-override: 90%;\n  descent-override: 22%;\n  line-gap-override: 0%;\n}\nbody {\n  font-family: 'Inter', 'Inter Fallback', sans-serif;\n}",{"id":763,"language":10,"code":764,"is_editable":749},366,"\u002F* unicode-range: download this file only when Latin characters are used *\u002F\n@font-face {\n  font-family: 'MyFont';\n  src: url('\u002Ffonts\u002Fmyfont-latin.woff2') format('woff2');\n  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;\n  font-display: swap;\n}\n\u002F* Arabic script subset (Urdu, Arabic) loads only when needed *\u002F\n@font-face {\n  font-family: 'MyFont';\n  src: url('\u002Ffonts\u002Fmyfont-arabic.woff2') format('woff2');\n  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFF;\n  font-display: swap;\n}",{"id":766,"language":767,"code":768,"is_editable":749},367,"javascript","\u002F\u002F Load a font with the CSS Font Loading API\nconst font = new FontFace('Inter', \"url('\u002Ffonts\u002Finter-400.woff2') format('woff2')\", { weight: '400', display: 'swap' });\n\nfont.load().then(loaded => {\n  document.fonts.add(loaded);\n  document.documentElement.classList.add('fonts-loaded');\n  console.log('Font loaded:', loaded.family);\n}).catch(err => console.log('Font failed, fallback stays:', err.message));\n\ndocument.fonts.ready.then(() => console.log('All fonts ready, count:', document.fonts.size));",[770,776,782],{"id":647,"title":771,"slug":772,"prompt":773,"starter_code":774,"expected_output":775,"language":10,"order_index":23},"Write an @font-face Rule","write-font-face-rule","Write an @font-face rule for the family name 'Lora' that loads \u002Ffonts\u002Flora-400.woff2 as WOFF2, is weight 400 and normal style, and shows fallback text immediately while loading. Then apply it to the body with a serif fallback.","\u002F* your @font-face rule here *\u002F\n\nbody {\n  \u002F* font-family here *\u002F\n}","An @font-face rule with src url('\u002Ffonts\u002Flora-400.woff2') format('woff2'), font-weight 400, font-style normal and font-display swap; body uses 'Lora', serif.",{"id":651,"title":777,"slug":778,"prompt":779,"starter_code":780,"expected_output":781,"language":10,"order_index":12},"Variable Font Declaration","variable-font-declaration","Declare a variable font family 'Roboto Flex VF' from \u002Ffonts\u002Froboto-flex.woff2 that supports every weight from 100 to 1000 and uses swap loading. Then style .title with weight 650 and .tag with the custom axis setting for 'wdth' set to 90 using font-variation-settings.","\u002F* your @font-face rule here *\u002F\n\n.title { \u002F* weight 650 *\u002F }\n.tag { \u002F* wdth 90 using font-variation-settings *\u002F }","@font-face declares font-weight: 100 1000; .title has font-weight: 650; .tag uses font-variation-settings: 'wdth' 90.",{"id":655,"title":783,"slug":784,"prompt":785,"starter_code":786,"expected_output":787,"language":767,"order_index":57},"Choose a font-display Value","choose-font-display-value","Write a function fontDisplay(kind) that returns the best font-display value: 'icons' returns 'block', 'body' returns 'swap', 'hero-brand' returns 'fallback', and 'performance-critical' returns 'optional'. For anything else return 'auto'.","function fontDisplay(kind) {\n  \u002F\u002F TODO: implement\n}\n\nconsole.log(fontDisplay('icons'));\nconsole.log(fontDisplay('body'));\nconsole.log(fontDisplay('performance-critical'));\nconsole.log(fontDisplay('other'));","block\nswap\noptional\nauto","2026-09-30T17:07:01+00:00",{"id":527,"slug":529,"title":528},{"id":535,"slug":537,"title":536}]