[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"tag-css-2":32,"tags-dev":156},[4,20],{"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","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","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.","Structured paths, listening drills and spaced repetition that actually sticks.","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,{"items":33,"meta":153},[34,68,86,103,120,137],{"id":35,"slug":36,"title":37,"subtitle":38,"excerpt":39,"coverUrl":40,"locale":13,"readingMinutes":41,"publishedAt":42,"viewCount":43,"likeCount":19,"commentCount":19,"author":44,"vertical":49,"topic":50,"tags":53,"_count":65,"playground":67,"hasQuiz":17,"hasPlayground":17},"019fe65f-f67a-7038-9c0d-874d6c8ece3c","css-property-registered-custom-properties","You can't transition a CSS variable. @property says otherwise.",null,"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",5,"2026-07-08T08:36:23.824Z",53,{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},"css","CSS",[54,56,59,62],{"slug":51,"name":55,"color":38},"Css",{"slug":57,"name":58,"color":38},"webdev","Webdev",{"slug":60,"name":61,"color":38},"frontend","Frontend",{"slug":63,"name":64,"color":38},"javascript","Javascript",{"assessments":66},1,{"slug":36},{"id":69,"slug":70,"title":71,"subtitle":38,"excerpt":72,"coverUrl":73,"locale":13,"readingMinutes":41,"publishedAt":74,"viewCount":75,"likeCount":19,"commentCount":19,"author":76,"vertical":77,"topic":78,"tags":79,"_count":84,"playground":85,"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","2026-07-06T10:47:02.014Z",48,{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},[80,81,82,83],{"slug":51,"name":55,"color":38},{"slug":57,"name":58,"color":38},{"slug":60,"name":61,"color":38},{"slug":63,"name":64,"color":38},{"assessments":66},{"slug":70},{"id":87,"slug":88,"title":89,"subtitle":38,"excerpt":90,"coverUrl":91,"locale":13,"readingMinutes":41,"publishedAt":92,"viewCount":93,"likeCount":19,"commentCount":19,"author":94,"vertical":95,"topic":96,"tags":97,"_count":102,"playground":38,"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",7,{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},[98,99,100,101],{"slug":51,"name":55,"color":38},{"slug":57,"name":58,"color":38},{"slug":60,"name":61,"color":38},{"slug":63,"name":64,"color":38},{"assessments":19},{"id":104,"slug":105,"title":106,"subtitle":38,"excerpt":107,"coverUrl":108,"locale":13,"readingMinutes":41,"publishedAt":109,"viewCount":110,"likeCount":19,"commentCount":19,"author":111,"vertical":112,"topic":113,"tags":114,"_count":119,"playground":38,"hasQuiz":18,"hasPlayground":18},"019fe65f-d8d6-73ed-b26b-18726a494914","view-transitions-native-page-transitions","The page transition you pay a library for is now free","You reach for Framer Motion or GSAP to make navigation feel smooth. The View Transitions API does the same thing natively — and the starting price is a single CSS rule.","\u002Fmedia\u002Fcovers\u002Fview-transitions-native-page-transitions.png","2026-07-03T09:26:36.534Z",8,{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},[115,116,117,118],{"slug":51,"name":55,"color":38},{"slug":57,"name":58,"color":38},{"slug":60,"name":61,"color":38},{"slug":63,"name":64,"color":38},{"assessments":19},{"id":121,"slug":122,"title":123,"subtitle":38,"excerpt":124,"coverUrl":125,"locale":13,"readingMinutes":126,"publishedAt":127,"viewCount":93,"likeCount":19,"commentCount":19,"author":128,"vertical":129,"topic":130,"tags":131,"_count":136,"playground":38,"hasQuiz":18,"hasPlayground":18},"019fe65f-d19a-709a-855e-54178d886feb","has-selector-condition-evaluator",":has() isn't a parent selector. It deletes JavaScript.","Everyone calls :has() the parent selector. That framing is too small — it's a condition evaluator that obsoletes a whole category of class-toggling JS, and it's in every browser today.","\u002Fmedia\u002Fcovers\u002Fhas-selector-condition-evaluator.png",4,"2026-07-02T07:18:03.500Z",{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},[132,133,134,135],{"slug":51,"name":55,"color":38},{"slug":57,"name":58,"color":38},{"slug":60,"name":61,"color":38},{"slug":63,"name":64,"color":38},{"assessments":19},{"id":138,"slug":139,"title":140,"subtitle":38,"excerpt":141,"coverUrl":142,"locale":13,"readingMinutes":126,"publishedAt":143,"viewCount":93,"likeCount":19,"commentCount":19,"author":144,"vertical":145,"topic":146,"tags":147,"_count":152,"playground":38,"hasQuiz":18,"hasPlayground":18},"019fe65f-c193-7159-96ba-bff62b34e53d","container-queries-responsive-primitive","Your card breaks in the sidebar. Here's the real fix.","A component that looks perfect in the main column falls apart in a sidebar — and the viewport width says everything's fine. The bug isn't your CSS. It's the question your CSS is asking.","\u002Fmedia\u002Fcovers\u002Fcontainer-queries-responsive-primitive.png","2026-06-30T07:30:01.218Z",{"id":45,"name":46,"username":47,"avatarUrl":38,"headline":48},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":51,"name":52},[148,149,150,151],{"slug":51,"name":55,"color":38},{"slug":57,"name":58,"color":38},{"slug":60,"name":61,"color":38},{"slug":63,"name":64,"color":38},{"assessments":19},{"page":31,"perPage":154,"total":155,"totalPages":31},12,18,[157,159,161,163,164,168,171,174,177,181,184],{"slug":57,"name":58,"color":38,"articles":158},50,{"slug":63,"name":64,"color":38,"articles":160},45,{"slug":60,"name":61,"color":38,"articles":162},44,{"slug":51,"name":55,"color":38,"articles":155},{"slug":165,"name":166,"color":38,"articles":167},"typescript","Typescript",9,{"slug":169,"name":170,"color":38,"articles":93},"performance","Performance",{"slug":172,"name":173,"color":38,"articles":41},"react","React",{"slug":175,"name":176,"color":38,"articles":126},"node","Node",{"slug":178,"name":179,"color":38,"articles":180},"ai","Ai",3,{"slug":182,"name":183,"color":38,"articles":180},"tutorial","Tutorial",{"slug":185,"name":186,"color":38,"articles":180},"html","Html"]