[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"tag-css-4":44,"search-suggestions":285,"tags-all":322},[4,20,32],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Read it. Run it. Prove it.","A post a day on modern web development — most with an editable playground and a quiz that explains every answer. Free, no account needed.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Grammar explained the way good documentation explains an API — one idea at a time, each with a quiz.","amber-400","⌘",[13,15,29],"es",{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":17,"packages":18,"community":17,"certificates":17,"teams":18,"commerce":18},2,{"id":33,"slug":34,"name":35,"tagline":36,"description":37,"accentFrom":38,"accentTo":39,"icon":40,"defaultLocale":13,"locales":41,"features":42,"position":43},"7b3c16f2-931d-410e-802e-e1fa4edab7de","soft","Soft Skills","The half of the job nobody wrote documentation for.","Weekly, on the parts of working life that decide more than your code does — first weeks, meetings, interviews, promotions, and the people around you. Written from what actually happens, and recorded as a podcast you can listen to on the walk.","emerald-400","teal-300","◉",[13],{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":18},3,{"items":45,"meta":282},[46,80,99,117,135,153,173,191,210,228,246,265],{"id":47,"slug":48,"title":49,"subtitle":50,"excerpt":51,"coverUrl":52,"locale":13,"readingMinutes":53,"publishedAt":54,"viewCount":55,"likeCount":19,"commentCount":19,"author":56,"vertical":61,"topic":62,"tags":65,"_count":77,"playground":79,"hasQuiz":17,"hasPlayground":17},"019fe660-b09d-731e-b160-9e45270a5652","css-scope-native-style-scoping","CSS has no native scoping. `@scope` changes that.",null,"BEM, CSS Modules, and scoped component styles all exist because CSS leaks — a rule written for one component can silently affect another. `@scope` gives the cascade a lower boundary so styles stay where you put them, natively, with no build step.","\u002Fmedia\u002Fcovers\u002Fcss-scope-native-style-scoping.png",5,"2026-07-31T08:56:20.507Z",607,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},"css","CSS",[66,68,71,74],{"slug":63,"name":67,"color":50},"Css",{"slug":69,"name":70,"color":50},"webdev","Webdev",{"slug":72,"name":73,"color":50},"frontend","Frontend",{"slug":75,"name":76,"color":50},"javascript","Javascript",{"assessments":78},1,{"slug":48},{"id":81,"slug":82,"title":83,"subtitle":50,"excerpt":84,"coverUrl":85,"locale":13,"readingMinutes":86,"publishedAt":87,"viewCount":88,"likeCount":19,"commentCount":19,"author":89,"vertical":90,"topic":91,"tags":92,"_count":97,"playground":98,"hasQuiz":17,"hasPlayground":17},"019fe660-a1fc-740c-9df4-b60a02de8afa","css-color-mix-native-color-mixing","You reach for Sass to mix colors. `color-mix()` does it natively.","Sass's `darken()`, `lighten()`, and `mix()` functions solved real problems CSS couldn't handle for decades. `color-mix()` is the native answer, and it ships in every modern browser with no build step required.","\u002Fmedia\u002Fcovers\u002Fcss-color-mix-native-color-mixing.png",4,"2026-07-29T08:47:34.803Z",552,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[93,94,95,96],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":82},{"id":100,"slug":101,"title":102,"subtitle":50,"excerpt":103,"coverUrl":104,"locale":13,"readingMinutes":86,"publishedAt":105,"viewCount":106,"likeCount":19,"commentCount":19,"author":107,"vertical":108,"topic":109,"tags":110,"_count":115,"playground":116,"hasQuiz":17,"hasPlayground":17},"019fe660-9a9b-73dc-87cd-48744e21e671","text-wrap-balance-headline-orphans","You hand-edit headlines to avoid orphaned words. `text-wrap: balance` does it natively.","The classic fix for a headline that breaks awkwardly — a manual `\u003Cbr>`, a `&shy;`, or a max-width tweak — exists because CSS had no way to distribute line breaks evenly. `text-wrap: balance` and `text-wrap: pretty` are the native answers.","\u002Fmedia\u002Fcovers\u002Ftext-wrap-balance-headline-orphans.png","2026-07-28T08:41:41.989Z",510,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[111,112,113,114],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":101},{"id":118,"slug":119,"title":120,"subtitle":50,"excerpt":121,"coverUrl":122,"locale":13,"readingMinutes":86,"publishedAt":123,"viewCount":124,"likeCount":19,"commentCount":19,"author":125,"vertical":126,"topic":127,"tags":128,"_count":133,"playground":134,"hasQuiz":17,"hasPlayground":17},"019fe660-7d17-745b-812d-b1e81a1b2b85","css-starting-style-entry-animations","You use a setTimeout to trigger CSS entry animations. `@starting-style` makes it unnecessary.","Before `@starting-style`, the moment an element entered the DOM was invisible to CSS — transitions had no 'before' state to interpolate from. The at-rule gives you one, natively, with no JavaScript required.","\u002Fmedia\u002Fcovers\u002Fcss-starting-style-entry-animations.png","2026-07-25T08:13:02.298Z",545,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[129,130,131,132],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":119},{"id":136,"slug":137,"title":138,"subtitle":50,"excerpt":139,"coverUrl":140,"locale":13,"readingMinutes":53,"publishedAt":141,"viewCount":142,"likeCount":19,"commentCount":19,"author":143,"vertical":144,"topic":145,"tags":146,"_count":151,"playground":152,"hasQuiz":17,"hasPlayground":17},"019fe660-48c5-70fe-a5b4-b20c5b2661e7","css-anchor-positioning","You're using Floating UI to position your tooltip. The browser does it natively now.","CSS Anchor Positioning is Baseline 2026 — it lets any element declare itself an anchor and any floating element position relative to it in pure CSS. No JavaScript, no layout math, no ResizeObserver wiring.","\u002Fmedia\u002Fcovers\u002Fcss-anchor-positioning.png","2026-07-18T07:59:42.250Z",541,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[147,148,149,150],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":137},{"id":154,"slug":155,"title":156,"subtitle":50,"excerpt":157,"coverUrl":158,"locale":13,"readingMinutes":53,"publishedAt":159,"viewCount":160,"likeCount":19,"commentCount":19,"author":161,"vertical":162,"topic":163,"tags":164,"_count":171,"playground":172,"hasQuiz":17,"hasPlayground":17},"019fe660-416e-7357-854c-5a7b56d68629","css-logical-properties","Your `margin-left` doesn't exist in Arabic. CSS logical properties fix that.","Physical CSS properties like `margin-left` and `padding-right` break silently when a layout needs to support right-to-left languages. Logical properties replace the physical axis with a writing-mode-aware model — one codebase, every direction.","\u002Fmedia\u002Fcovers\u002Fcss-logical-properties.png","2026-07-17T08:18:05.044Z",604,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[165,166,167,168],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":169,"name":170,"color":50},"html","Html",{"assessments":78},{"slug":155},{"id":174,"slug":175,"title":176,"subtitle":50,"excerpt":177,"coverUrl":178,"locale":13,"readingMinutes":53,"publishedAt":179,"viewCount":180,"likeCount":19,"commentCount":19,"author":181,"vertical":182,"topic":183,"tags":184,"_count":189,"playground":190,"hasQuiz":17,"hasPlayground":17},"019fe660-39f9-768b-be22-fcd49b6abf6d","css-subgrid-nested-grid-alignment","Your CSS Grid cards look misaligned. `subgrid` is the fix you didn't know existed.","CSS Grid controls your outer container, but its children can't participate in the same tracks. `subgrid` closes that gap — nested elements align to the parent grid's rows and columns without padding hacks, fixed heights, or JavaScript measurements.","\u002Fmedia\u002Fcovers\u002Fcss-subgrid-nested-grid-alignment.png","2026-07-16T08:21:27.248Z",838,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[185,186,187,188],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":169,"name":170,"color":50},{"assessments":78},{"slug":175},{"id":192,"slug":193,"title":194,"subtitle":50,"excerpt":195,"coverUrl":196,"locale":13,"readingMinutes":86,"publishedAt":197,"viewCount":198,"likeCount":19,"commentCount":19,"author":199,"vertical":200,"topic":201,"tags":203,"_count":208,"playground":209,"hasQuiz":17,"hasPlayground":17},"019fe660-1462-723e-9605-66ffa7e98f42","popover-api-native-popovers","Your dropdown is a div. The browser has a native popover now.","Custom dropdowns, tooltips, and menus built with stacked divs and click-outside listeners — the Popover API landed in every browser in 2024, and the baseline version is two HTML attributes.","\u002Fmedia\u002Fcovers\u002Fpopover-api-native-popovers.png","2026-07-12T08:24:42.323Z",484,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":202},"JavaScript",[204,205,206,207],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":193},{"id":211,"slug":212,"title":213,"subtitle":50,"excerpt":214,"coverUrl":215,"locale":13,"readingMinutes":53,"publishedAt":216,"viewCount":217,"likeCount":19,"commentCount":19,"author":218,"vertical":219,"topic":220,"tags":221,"_count":226,"playground":227,"hasQuiz":17,"hasPlayground":17},"019fe65f-fe39-767c-9ce8-da4db5144b1d","css-nesting-sass-replaced","You kept Sass for one reason. Native CSS nesting just ended it.","CSS has supported nesting natively since 2023 — pseudo-classes, pseudo-elements, and @media queries nested inside the rules they belong to. No compiler required.","\u002Fmedia\u002Fcovers\u002Fcss-nesting-sass-replaced.png","2026-07-09T09:48:41.505Z",388,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[222,223,224,225],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":212},{"id":229,"slug":230,"title":231,"subtitle":50,"excerpt":232,"coverUrl":233,"locale":13,"readingMinutes":53,"publishedAt":234,"viewCount":235,"likeCount":19,"commentCount":19,"author":236,"vertical":237,"topic":238,"tags":239,"_count":244,"playground":245,"hasQuiz":17,"hasPlayground":17},"019fe65f-f67a-7038-9c0d-874d6c8ece3c","css-property-registered-custom-properties","You can't transition a CSS variable. @property says otherwise.","CSS custom properties are string substitution — the browser doesn't know a number from a color. Register one with @property and it gains a real type, an initial value, and the ability to animate.","\u002Fmedia\u002Fcovers\u002Fcss-property-registered-custom-properties.png","2026-07-08T08:36:23.824Z",613,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[240,241,242,243],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":230},{"id":247,"slug":248,"title":249,"subtitle":50,"excerpt":250,"coverUrl":251,"locale":13,"readingMinutes":252,"publishedAt":253,"viewCount":254,"likeCount":19,"commentCount":19,"author":255,"vertical":256,"topic":257,"tags":258,"_count":263,"playground":264,"hasQuiz":17,"hasPlayground":17},"019fe65f-ef22-765a-97c7-cdfdbb168024","scroll-driven-animations","Your scroll listener is doing CSS's job","Reading progress bars, reveal-on-scroll effects, parallax — you've been writing these in JavaScript. CSS scroll-driven animations bind them directly to scroll position, off the main thread, in a handful of lines.","\u002Fmedia\u002Fcovers\u002Fscroll-driven-animations.png",6,"2026-07-06T10:47:02.014Z",453,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[259,260,261,262],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":248},{"id":266,"slug":267,"title":268,"subtitle":50,"excerpt":269,"coverUrl":270,"locale":13,"readingMinutes":53,"publishedAt":271,"viewCount":272,"likeCount":19,"commentCount":19,"author":273,"vertical":274,"topic":275,"tags":276,"_count":281,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-e05c-77bb-b8a3-cb8dbdc99346","css-layer-architecture","You reached for !important again. @layer is the real fix.","When a third-party reset beats your styles and your own utilities lose to an ancient nested rule, the problem isn't your selectors. It's that your stylesheet has no architecture. @layer adds one.","\u002Fmedia\u002Fcovers\u002Fcss-layer-architecture.png","2026-07-04T08:44:02.193Z",175,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[277,278,279,280],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"page":86,"perPage":283,"total":284,"totalPages":53},12,51,[286,288,290,292,296,297,301,305,309,313,317,321],{"slug":69,"name":70,"articles":287},174,{"slug":75,"name":76,"articles":289},141,{"slug":72,"name":73,"articles":291},96,{"slug":293,"name":294,"articles":295},"tutorial","Tutorial",71,{"slug":63,"name":67,"articles":284},{"slug":298,"name":299,"articles":300},"performance","Performance",30,{"slug":302,"name":303,"articles":304},"typescript","Typescript",25,{"slug":306,"name":307,"articles":308},"react","React",20,{"slug":310,"name":311,"articles":312},"programming","Programming",19,{"slug":314,"name":315,"articles":316},"browser","Browser",18,{"slug":318,"name":319,"articles":320},"node","Node",16,{"slug":169,"name":170,"articles":283},[323,324,325,326,327,328,329,330,331,332,333,334,335,339,343,346,350,354,357,360,364,367,370,373,376,379,382,385,388,391,394,397,400,403,406,409,412,415,418,421],{"slug":69,"name":70,"color":50,"articles":287},{"slug":75,"name":76,"color":50,"articles":289},{"slug":72,"name":73,"color":50,"articles":291},{"slug":293,"name":294,"color":50,"articles":295},{"slug":63,"name":67,"color":50,"articles":284},{"slug":298,"name":299,"color":50,"articles":300},{"slug":302,"name":303,"color":50,"articles":304},{"slug":306,"name":307,"color":50,"articles":308},{"slug":310,"name":311,"color":50,"articles":312},{"slug":314,"name":315,"color":50,"articles":316},{"slug":318,"name":319,"color":50,"articles":320},{"slug":169,"name":170,"color":50,"articles":283},{"slug":336,"name":337,"color":50,"articles":338},"nextjs","Nextjs",11,{"slug":340,"name":341,"color":50,"articles":342},"vue","Vue",10,{"slug":344,"name":345,"color":50,"articles":342},"accessibility","Accessibility",{"slug":347,"name":348,"color":50,"articles":349},"nestjs","Nestjs",9,{"slug":351,"name":352,"color":50,"articles":353},"nuxt","Nuxt",8,{"slug":355,"name":356,"color":50,"articles":353},"career","Career",{"slug":358,"name":359,"color":50,"articles":353},"discuss","Discuss",{"slug":361,"name":362,"color":50,"articles":363},"beginners","Beginners",7,{"slug":365,"name":366,"color":50,"articles":363},"productivity","Productivity",{"slug":368,"name":369,"color":50,"articles":252},"grammar","Grammar",{"slug":371,"name":372,"color":50,"articles":53},"security","Security",{"slug":374,"name":375,"color":50,"articles":86},"ssr","SSR",{"slug":377,"name":378,"color":50,"articles":86},"apis","Apis",{"slug":380,"name":381,"color":50,"articles":43},"ai","Ai",{"slug":383,"name":384,"color":50,"articles":43},"api","API",{"slug":386,"name":387,"color":50,"articles":43},"caching","Caching",{"slug":389,"name":390,"color":50,"articles":31},"async","Async",{"slug":392,"name":393,"color":50,"articles":31},"forms","Forms",{"slug":395,"name":396,"color":50,"articles":31},"dom","Dom",{"slug":398,"name":399,"color":50,"articles":31},"backend","Backend",{"slug":401,"name":402,"color":50,"articles":31},"english","English",{"slug":404,"name":405,"color":50,"articles":31},"verbs","Verbs",{"slug":407,"name":408,"color":50,"articles":31},"spanish","Spanish",{"slug":410,"name":411,"color":50,"articles":31},"a1","A1",{"slug":413,"name":414,"color":50,"articles":31},"a2","A2",{"slug":416,"name":417,"color":50,"articles":31},"tenses","Tenses",{"slug":419,"name":420,"color":50,"articles":31},"turkish","Turkish",{"slug":422,"name":423,"color":50,"articles":31},"animation","Animation"]