[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"article-css-accent-color-native-form-control-tinting":44,"search-suggestions":197,"related-css-accent-color-native-form-control-tinting":238,"code:css:true:1vt92n0":365,"code:css:true:15i75qh":366,"comments-01a061c4-985b-758b-86a4-21f6b2fd81f8":367},[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,{"id":45,"slug":46,"title":47,"subtitle":48,"excerpt":49,"coverUrl":50,"locale":13,"readingMinutes":51,"publishedAt":52,"viewCount":53,"likeCount":19,"commentCount":19,"author":54,"vertical":59,"topic":60,"tags":63,"_count":75,"playground":77,"body":79,"bodyMd":180,"seo":181,"translationGroupId":184,"series":48,"podcastUrl":48,"verticalId":5,"thread":185,"assessments":187,"translations":193,"quiz":195},"01a061c4-985b-758b-86a4-21f6b2fd81f8","css-accent-color-native-form-control-tinting","One CSS Property Replaces Your Checkbox Hack",null,"Recoloring a checkbox to match the brand usually means appearance: none, a hand-drawn checkmark, and a rebuilt focus ring. accent-color does the same job in one line — and knowing where it stops matters as much as knowing that it works.","\u002Fmedia\u002Fcovers\u002Fcss-accent-color-native-form-control-tinting.png",4,"2026-09-07T12:02:34.132Z",57,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},"css","CSS",[64,66,69,72],{"slug":61,"name":65,"color":48},"Css",{"slug":67,"name":68,"color":48},"webdev","Webdev",{"slug":70,"name":71,"color":48},"frontend","Frontend",{"slug":73,"name":74,"color":48},"accessibility","Accessibility",{"assessments":76},1,{"slug":46,"title":78},"accent-color — interactive playground",{"blocks":80,"version":76},[81,85,90,93,96,100,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173],{"id":82,"html":83,"type":84},"b1","\u003Cp>Someone on the design side wants the checkboxes to match the brand&#39;s indigo instead of the browser&#39;s default blue. Reasonable ask. So you open the CSS file and start down the well-worn path:\u003C\u002Fp>","paragraph",{"id":86,"code":87,"type":88,"language":61,"highlight":89},"b2","input[type=\"checkbox\"] {\n  appearance: none;\n  width: 18px;\n  height: 18px;\n  border: 2px solid #6366f1;\n  border-radius: 4px;\n  position: relative;\n}\n\ninput[type=\"checkbox\"]:checked {\n  background: #6366f1;\n}\n\ninput[type=\"checkbox\"]:checked::after {\n  content: \"\";\n  position: absolute;\n  inset: 3px;\n  background: url(\"data:image\u002Fsvg+xml,...\") no-repeat center;\n}\n\ninput[type=\"checkbox\"]:focus-visible {\n  outline: 2px solid #6366f1;\n  outline-offset: 2px;\n}","code",[],{"id":91,"html":92,"type":84},"b3","\u003Cp>That compiles, it looks right in the design review, and it&#39;s already an hour of work for one control. Now do the radio buttons. Now do the range slider — no \u003Ccode>::after\u003C\u002Fcode> trick works there, you&#39;re overriding \u003Ccode>::-webkit-slider-thumb\u003C\u002Fcode> and \u003Ccode>::-moz-range-thumb\u003C\u002Fcode> separately because no shorthand covers both engines. Now someone files a bug: the checkbox lost its indeterminate state, because you rebuilt \u003Ccode>:checked\u003C\u002Fcode> and forgot \u003Ccode>:indeterminate\u003C\u002Fcode> existed.\u003C\u002Fp>",{"id":94,"html":95,"type":84},"b4","\u003Cp>You didn&#39;t reskin a checkbox. You reimplemented one, badly, one state at a time.\u003C\u002Fp>",{"id":97,"html":98,"text":98,"type":99,"level":31},"b5","The property that does the actual job","heading",{"id":101,"code":102,"type":88,"language":61,"highlight":103},"b6",":root {\n  accent-color: #6366f1;\n}",[],{"id":105,"html":106,"type":84},"b7","\u003Cp>One declaration, set once, at the root. Every checkbox, radio button, range slider, and progress bar under it now tints indigo — no \u003Ccode>appearance: none\u003C\u002Fcode>, no hand-drawn checkmark, no rebuilt focus ring, because you never took the native control apart in the first place. \u003Ccode>accent-color\u003C\u002Fcode> is an inherited property, which is exactly why setting it at \u003Ccode>:root\u003C\u002Fcode> is enough; it flows down to every form control in the document the same way \u003Ccode>color\u003C\u002Fcode> flows down to every piece of text.\u003C\u002Fp>",{"id":108,"html":109,"type":84},"b8","\u003Cp>The browser keeps drawing the control the way it always has — rounded on iOS, square-ish on Windows, whatever the platform&#39;s native checkbox looks like — and just swaps the accent hue: the check itself, the radio dot, the slider&#39;s thumb and filled track, the progress bar&#39;s value fill. You get a colored control that still behaves like a real one, with every state you didn&#39;t have to write: \u003Ccode>:hover\u003C\u002Fcode>, \u003Ccode>:disabled\u003C\u002Fcode>, \u003Ccode>:indeterminate\u003C\u002Fcode>, keyboard focus, screen-reader semantics, all still wired up because the browser is still the one doing the wiring.\u003C\u002Fp>",{"id":111,"html":112,"type":84},"b9","\u003Cp>Try that against your own instinct for a second: pick a color, and watch which controls actually pick it up.\u003C\u002Fp>",{"id":114,"html":115,"type":84},"b10","\u003C!-- playground:start -->",{"id":117,"html":118,"text":118,"type":99,"level":31},"b11","🎮 Try it yourself",{"id":120,"html":121,"type":84},"b12","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-accent-color-native-form-control-tinting\u002Fplayground\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":123,"html":124,"type":84},"b13","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":126,"html":127,"type":84},"b14","\u003C!-- playground:end -->",{"id":129,"html":130,"text":130,"type":99,"level":31},"b15","Where it stops — and where it should",{"id":132,"html":133,"type":84},"b16","\u003Cp>\u003Ccode>accent-color\u003C\u002Fcode> reaches four things: \u003Ccode>checkbox\u003C\u002Fcode>, \u003Ccode>radio\u003C\u002Fcode>, \u003Ccode>range\u003C\u002Fcode>, and \u003Ccode>progress\u003C\u002Fcode>. Notably absent: \u003Ccode>&lt;meter&gt;\u003C\u002Fcode>. Despite looking like a close cousin of \u003Ccode>&lt;progress&gt;\u003C\u002Fcode>, \u003Ccode>meter\u003C\u002Fcode> colors its value bar through separate, less standardized hooks — dropping \u003Ccode>accent-color\u003C\u002Fcode> on it does nothing, and that&#39;s spec behavior, not a bug in your stylesheet.\u003C\u002Fp>",{"id":135,"html":136,"type":84},"b17","\u003Cp>And here&#39;s the part that trips people up after they&#39;ve already adopted it: if you&#39;ve \u003Cem>already\u003C\u002Fem> gone the \u003Ccode>appearance: none\u003C\u002Fcode> route on a control — drawn your own box, your own checkmark, your own thumb — \u003Ccode>accent-color\u003C\u002Fcode> has nothing left to tint. It only recolors the browser&#39;s own native rendering path. Take that rendering away, and you&#39;re back to owning every pixel and every state yourself, by hand, same as before. \u003Ccode>accent-color\u003C\u002Fcode> isn&#39;t a way to \u003Cem>further\u003C\u002Fem> customize a control you&#39;ve already rebuilt; it&#39;s a reason to not rebuild it in the first place.\u003C\u002Fp>",{"id":138,"html":139,"type":84},"b18","\u003Cp>One more honest caveat, and it&#39;s a feature, not a limitation: on a system running a high-contrast mode — Windows&#39; \u003Ccode>forced-colors\u003C\u002Fcode>, for instance — the OS is allowed to override \u003Ccode>accent-color\u003C\u002Fcode> along with most other author-specified colors, to guarantee the contrast the user configured actually holds. Your indigo can vanish there on purpose. That&#39;s the platform doing its job, not the property failing at its own one purpose.\u003C\u002Fp>",{"id":141,"html":142,"text":142,"type":99,"level":31},"b19","The one-line version, for real this time",{"id":144,"html":145,"type":84},"b20","\u003Cp>Back to that hour spent on one checkbox: subtract the \u003Ccode>appearance: none\u003C\u002Fcode>, the pseudo-element checkmark, the two vendor-prefixed thumb selectors, the rebuilt focus ring — and what&#39;s left to write by hand is the indeterminate state, because that one&#39;s still yours regardless. Everything else was already built. \u003Ccode>accent-color\u003C\u002Fcode> was just never told to use it.\u003C\u002Fp>",{"id":147,"html":148,"type":84},"b21","\u003C!-- quiz:start -->",{"id":150,"html":151,"text":151,"type":99,"level":31},"b22","🧠 Test yourself",{"id":153,"html":154,"type":84},"b23","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-accent-color-native-form-control-tinting\u002Fquiz\">Take the 8-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":156,"html":157,"type":84},"b24","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":159,"html":160,"type":84},"b25","\u003C!-- quiz:end -->",{"id":162,"html":163,"type":84},"b26","\u003Cp>Next time someone asks for brand-colored checkboxes, how much of that request can you answer with a single line at \u003Ccode>:root\u003C\u002Fcode> — and how much of your existing form CSS was solving a problem this property already solves for free?\u003C\u002Fp>",{"id":165,"type":166},"b27","divider",{"id":168,"html":169,"type":84},"b28","\u003Cp>🚀 \u003Cstrong>Want more like this?\u003C\u002Fstrong> Every guide, playground, and quiz lives on \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">bestpractic.org\u003C\u002Fa>\u003C\u002Fstrong> — open it and \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002F\">sign up free\u003C\u002Fa>\u003C\u002Fstrong> so the next one finds you.\u003C\u002Fp>",{"id":171,"html":172,"type":84},"b29","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":174,"type":175,"items":176,"ordered":18},"b30","list",[177,178,179],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","Someone on the design side wants the checkboxes to match the brand's indigo instead of the browser's default blue. Reasonable ask. So you open the CSS file and start down the well-worn path:\n\n```css\ninput[type=\"checkbox\"] {\n  appearance: none;\n  width: 18px;\n  height: 18px;\n  border: 2px solid #6366f1;\n  border-radius: 4px;\n  position: relative;\n}\n\ninput[type=\"checkbox\"]:checked {\n  background: #6366f1;\n}\n\ninput[type=\"checkbox\"]:checked::after {\n  content: \"\";\n  position: absolute;\n  inset: 3px;\n  background: url(\"data:image\u002Fsvg+xml,...\") no-repeat center;\n}\n\ninput[type=\"checkbox\"]:focus-visible {\n  outline: 2px solid #6366f1;\n  outline-offset: 2px;\n}\n```\n\nThat compiles, it looks right in the design review, and it's already an hour of work for one control. Now do the radio buttons. Now do the range slider — no `::after` trick works there, you're overriding `::-webkit-slider-thumb` and `::-moz-range-thumb` separately because no shorthand covers both engines. Now someone files a bug: the checkbox lost its indeterminate state, because you rebuilt `:checked` and forgot `:indeterminate` existed.\n\nYou didn't reskin a checkbox. You reimplemented one, badly, one state at a time.\n\n## The property that does the actual job\n\n```css\n:root {\n  accent-color: #6366f1;\n}\n```\n\nOne declaration, set once, at the root. Every checkbox, radio button, range slider, and progress bar under it now tints indigo — no `appearance: none`, no hand-drawn checkmark, no rebuilt focus ring, because you never took the native control apart in the first place. `accent-color` is an inherited property, which is exactly why setting it at `:root` is enough; it flows down to every form control in the document the same way `color` flows down to every piece of text.\n\nThe browser keeps drawing the control the way it always has — rounded on iOS, square-ish on Windows, whatever the platform's native checkbox looks like — and just swaps the accent hue: the check itself, the radio dot, the slider's thumb and filled track, the progress bar's value fill. You get a colored control that still behaves like a real one, with every state you didn't have to write: `:hover`, `:disabled`, `:indeterminate`, keyboard focus, screen-reader semantics, all still wired up because the browser is still the one doing the wiring.\n\nTry that against your own instinct for a second: pick a color, and watch which controls actually pick it up.\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-accent-color-native-form-control-tinting\u002Fplayground)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## Where it stops — and where it should\n\n`accent-color` reaches four things: `checkbox`, `radio`, `range`, and `progress`. Notably absent: `\u003Cmeter>`. Despite looking like a close cousin of `\u003Cprogress>`, `meter` colors its value bar through separate, less standardized hooks — dropping `accent-color` on it does nothing, and that's spec behavior, not a bug in your stylesheet.\n\nAnd here's the part that trips people up after they've already adopted it: if you've *already* gone the `appearance: none` route on a control — drawn your own box, your own checkmark, your own thumb — `accent-color` has nothing left to tint. It only recolors the browser's own native rendering path. Take that rendering away, and you're back to owning every pixel and every state yourself, by hand, same as before. `accent-color` isn't a way to *further* customize a control you've already rebuilt; it's a reason to not rebuild it in the first place.\n\nOne more honest caveat, and it's a feature, not a limitation: on a system running a high-contrast mode — Windows' `forced-colors`, for instance — the OS is allowed to override `accent-color` along with most other author-specified colors, to guarantee the contrast the user configured actually holds. Your indigo can vanish there on purpose. That's the platform doing its job, not the property failing at its own one purpose.\n\n## The one-line version, for real this time\n\nBack to that hour spent on one checkbox: subtract the `appearance: none`, the pseudo-element checkmark, the two vendor-prefixed thumb selectors, the rebuilt focus ring — and what's left to write by hand is the indeterminate state, because that one's still yours regardless. Everything else was already built. `accent-color` was just never told to use it.\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 8-question quiz →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-accent-color-native-form-control-tinting\u002Fquiz)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\nNext time someone asks for brand-colored checkboxes, how much of that request can you answer with a single line at `:root` — and how much of your existing form CSS was solving a problem this property already solves for free?\n\n---\n\n🚀 **Want more like this?** Every guide, playground, and quiz lives on **[bestpractic.org](https:\u002F\u002Fbestpractic.org\u002F)** — open it and **[sign up free](https:\u002F\u002Fbestpractic.org\u002F)** so the next one finds you.\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)",{"title":47,"canonical":182,"description":183},"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fcss-accent-color-native-form-control-tinting","Recoloring a checkbox to match the brand usually means appearance: none, a hand-drawn checkmark, and a rebuilt focus ring. accent-color does the same job in one line — and knowing ","01a061c4-985b-758b-86a4-248f7ae20192",{"id":186,"locked":18},"01a061c4-98a3-7403-9a5b-b87f9f67c649",[188],{"id":189,"slug":46,"title":190,"_count":191},"01a061c4-98ce-774f-9221-5219ae0b898b","accent-color",{"questions":192},8,[194],{"locale":13,"slug":46},{"id":189,"slug":46,"title":190,"_count":196,"questionCount":192},{"questions":192},[198,200,204,206,208,212,216,220,224,228,231,235],{"slug":67,"name":68,"articles":199},84,{"slug":201,"name":202,"articles":203},"javascript","Javascript",70,{"slug":70,"name":71,"articles":205},68,{"slug":61,"name":65,"articles":207},30,{"slug":209,"name":210,"articles":211},"tutorial","Tutorial",18,{"slug":213,"name":214,"articles":215},"performance","Performance",12,{"slug":217,"name":218,"articles":219},"typescript","Typescript",11,{"slug":221,"name":222,"articles":223},"react","React",9,{"slug":225,"name":226,"articles":227},"browser","Browser",6,{"slug":229,"name":230,"articles":227},"grammar","Grammar",{"slug":232,"name":233,"articles":234},"html","Html",5,{"slug":236,"name":237,"articles":234},"node","Node",{"items":239,"meta":363},[240,252,270,288,306,324,343],{"id":45,"slug":46,"title":47,"subtitle":48,"excerpt":49,"coverUrl":50,"locale":13,"readingMinutes":51,"publishedAt":52,"viewCount":241,"likeCount":19,"commentCount":19,"author":242,"vertical":243,"topic":244,"tags":245,"_count":250,"playground":251,"hasQuiz":17,"hasPlayground":17},58,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[246,247,248,249],{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"slug":73,"name":74,"color":48},{"assessments":76},{"slug":46},{"id":253,"slug":254,"title":255,"subtitle":48,"excerpt":256,"coverUrl":257,"locale":13,"readingMinutes":227,"publishedAt":258,"viewCount":259,"likeCount":19,"commentCount":19,"author":260,"vertical":261,"topic":262,"tags":263,"_count":268,"playground":269,"hasQuiz":17,"hasPlayground":17},"01a037b3-f71a-755b-9820-9f2489daaebd","css-aspect-ratio-replace-padding-hack","Delete Your padding-bottom Aspect-Ratio Hack","For a decade the only way to keep a responsive box's shape was a padding percentage and an absolutely positioned wrapper. One CSS property replaces it — with one gotcha on real images nobody warns you about.","\u002Fmedia\u002Fcovers\u002Fcss-aspect-ratio-replace-padding-hack.png","2026-08-30T11:36:40.014Z",225,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[264,265,266,267],{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"slug":209,"name":210,"color":48},{"assessments":76},{"slug":254},{"id":271,"slug":272,"title":273,"subtitle":48,"excerpt":274,"coverUrl":275,"locale":13,"readingMinutes":51,"publishedAt":276,"viewCount":277,"likeCount":19,"commentCount":19,"author":278,"vertical":279,"topic":280,"tags":281,"_count":286,"playground":287,"hasQuiz":17,"hasPlayground":17},"01a03297-a2d3-7318-bffe-5edb58824c5d","css-focus-visible-keyboard-focus-rings","The outline: none Debate Has Been Over Since 2020","A designer flags the ugly blue focus ring in review. An engineer deletes it with outline: none. Nobody notices the keyboard-only user who now can't tell where they are on the page.","\u002Fmedia\u002Fcovers\u002Fcss-focus-visible-keyboard-focus-rings.png","2026-08-29T12:32:09.792Z",205,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[282,283,284,285],{"slug":61,"name":65,"color":48},{"slug":73,"name":74,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"assessments":76},{"slug":272},{"id":289,"slug":290,"title":291,"subtitle":48,"excerpt":292,"coverUrl":293,"locale":13,"readingMinutes":234,"publishedAt":294,"viewCount":295,"likeCount":19,"commentCount":19,"author":296,"vertical":297,"topic":298,"tags":299,"_count":304,"playground":305,"hasQuiz":17,"hasPlayground":17},"01a02d61-19cf-72cd-8490-a59e14f8839c","css-grid-auto-fit-vs-auto-fill","Your Grid Has Invisible Columns: auto-fill vs auto-fit","A responsive card grid that works perfectly with twelve items breaks with two — not from a bug, but from one word in a repeat() you copy-pasted without reading.","\u002Fmedia\u002Fcovers\u002Fcss-grid-auto-fit-vs-auto-fill.png","2026-08-28T17:00:06.666Z",376,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[300,301,302,303],{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"slug":209,"name":210,"color":48},{"assessments":76},{"slug":290},{"id":307,"slug":308,"title":309,"subtitle":48,"excerpt":310,"coverUrl":311,"locale":13,"readingMinutes":234,"publishedAt":312,"viewCount":313,"likeCount":19,"commentCount":19,"author":314,"vertical":315,"topic":316,"tags":317,"_count":322,"playground":323,"hasQuiz":17,"hasPlayground":17},"01a02319-4485-7310-b494-dc94bdbfb49c","css-field-sizing-auto-grow-textarea","Delete Your Auto-Resize Textarea JS. CSS Does It Now.","The scrollHeight hack everyone copy-pastes for auto-growing textareas has a one-line CSS replacement — plus the one gotcha that bites if you skip max-height.","\u002Fmedia\u002Fcovers\u002Fcss-field-sizing-auto-grow-textarea.png","2026-08-26T06:56:38.974Z",278,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[318,319,320,321],{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"slug":201,"name":202,"color":48},{"assessments":76},{"slug":308},{"id":325,"slug":326,"title":327,"subtitle":48,"excerpt":328,"coverUrl":329,"locale":13,"readingMinutes":234,"publishedAt":330,"viewCount":331,"likeCount":19,"commentCount":19,"author":332,"vertical":333,"topic":334,"tags":336,"_count":341,"playground":342,"hasQuiz":17,"hasPlayground":17},"01a01df1-d6d5-71e8-bba6-1242e581730b","web-animations-api-imperative-control","CSS Animations Can't Pause. The Web Animations API Can.","Toggling a class to restart a CSS animation works — until you need to pause it, reverse it mid-flight, or ask how far through it is. element.animate() returns an object with those methods built in, natively, in every browser you already support.","\u002Fmedia\u002Fcovers\u002Fweb-animations-api-imperative-control.png","2026-08-25T06:55:40.108Z",325,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":201,"name":335},"JavaScript",[337,338,339,340],{"slug":201,"name":202,"color":48},{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"assessments":76},{"slug":326},{"id":344,"slug":345,"title":346,"subtitle":48,"excerpt":347,"coverUrl":348,"locale":13,"readingMinutes":234,"publishedAt":349,"viewCount":350,"likeCount":19,"commentCount":19,"author":351,"vertical":352,"topic":353,"tags":354,"_count":361,"playground":362,"hasQuiz":17,"hasPlayground":17},"01a018ca-59cf-75a0-b0c2-ba8ca95ade59","css-where-is-specificity-control","The CSS Selector Built to Lose Every Fight","You keep reaching for !important to override a component's styles. There's a selector that fixes this by contributing zero specificity, on purpose.","\u002Fmedia\u002Fcovers\u002Fcss-where-is-specificity-control.png","2026-08-24T07:06:37.051Z",319,{"id":55,"name":56,"username":57,"avatarUrl":48,"headline":58},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":61,"name":62},[355,356,357,358],{"slug":61,"name":65,"color":48},{"slug":67,"name":68,"color":48},{"slug":70,"name":71,"color":48},{"slug":359,"name":360,"color":48},"programming","Programming",{"assessments":76},{"slug":345},{"page":76,"perPage":364,"total":207,"totalPages":234},7,"\u003Cdiv class=\"shj shj-lang-css shj-multiline\" data-lang=\"css\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003Cdiv>11\u003C\u002Fdiv>\u003Cdiv>12\u003C\u002Fdiv>\u003Cdiv>13\u003C\u002Fdiv>\u003Cdiv>14\u003C\u002Fdiv>\u003Cdiv>15\u003C\u002Fdiv>\u003Cdiv>16\u003C\u002Fdiv>\u003Cdiv>17\u003C\u002Fdiv>\u003Cdiv>18\u003C\u002Fdiv>\u003Cdiv>19\u003C\u002Fdiv>\u003Cdiv>20\u003C\u002Fdiv>\u003Cdiv>21\u003C\u002Fdiv>\u003Cdiv>22\u003C\u002Fdiv>\u003Cdiv>23\u003C\u002Fdiv>\u003Cdiv>24\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">input\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">type\u003C\u002Fspan>=\u003Cspan class=\"shj-str\">\"checkbox\"\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-var\">appearance\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">none\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">width\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">18\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">height\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">18\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">border\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">2\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan> \u003Cspan class=\"shj-num\">solid\u003C\u002Fspan> \u003Cspan class=\"shj-num\">#6366f1\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">border-radius\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">4\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">position\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">relative\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">input\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">type\u003C\u002Fspan>=\u003Cspan class=\"shj-str\">\"checkbox\"\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-var\">:checked\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-var\">background\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">#6366f1\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">input\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">type\u003C\u002Fspan>=\u003Cspan class=\"shj-str\">\"checkbox\"\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-var\">:checked\u003C\u002Fspan>\u003Cspan class=\"shj-var\">::after\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-var\">content\u003C\u002Fspan>: \u003Cspan class=\"shj-str\">\"\"\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">position\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">absolute\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">inset\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">3\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">background\u003C\u002Fspan>: \u003Cspan class=\"shj-func\">url\u003C\u002Fspan>(\u003Cspan class=\"shj-str\">\"data:image\u002Fsvg+xml,...\"\u003C\u002Fspan>) \u003Cspan class=\"shj-num\">no-repeat\u003C\u002Fspan> \u003Cspan class=\"shj-num\">center\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">input\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">type\u003C\u002Fspan>=\u003Cspan class=\"shj-str\">\"checkbox\"\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-var\">:focus-visible\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-var\">outline\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">2\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan> \u003Cspan class=\"shj-num\">solid\u003C\u002Fspan> \u003Cspan class=\"shj-num\">#6366f1\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-var\">outline-offset\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">2\u003C\u002Fspan>\u003Cspan class=\"shj-var\">px\u003C\u002Fspan>\u003Cspan class=\"shj-num\">\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-css shj-multiline\" data-lang=\"css\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-var\">:root\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-var\">accent-color\u003C\u002Fspan>: \u003Cspan class=\"shj-num\">#6366f1\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>",{"locked":18,"total":19,"comments":368},[]]