Library to rectify mistakes in the design of CSS. npmx.dev/package/@declanchidlow/fixcss
webdev front-end css fixcss
8

Configure Feed

Select the types of activity you want to include in your feed.

Add LICENSE file

Declan Chidlow (Jul 1, 2026, 2:08 PM +0800) cf5df5bb 6bd0b7e6

+34 -13
+21
LICENSE
··· 1 + MIT License 2 + 3 + Copyright (c) 2026 Declan Chidlow 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+12 -12
fixcss.js
··· 181 181 return before + fixed + brace; 182 182 }); 183 183 184 - // Phase 5: Fix property names and values inside declaration blocks 184 + // Fix property names and values inside declaration blocks 185 185 result = result.replace(/\{([^}]*)\}/g, function (match, declarations) { 186 186 var fixed = declarations; 187 187 188 - // 5a: Fix property names 188 + // Fix property names 189 189 for (var prop in PROPERTY_FIXES) { 190 190 var escapedProp = prop.replace(/([.*+?^${}()|[\]\\])/g, "\\$1"); 191 191 var propRegex = new RegExp("(^|[;\\s\\n])(" + escapedProp + ")\\s*:", "g"); ··· 194 194 }); 195 195 } 196 196 197 - // 5b: Fix display values (#37 — marked-block -> list-item, now that display-type -> display) 197 + // Fix display values (#37 — marked-block -> list-item, now that display-type -> display) 198 198 fixed = fixed.replace(/display\s*:\s*([^;!}]+)/g, function (m, val) { 199 199 var trimmed = val.trim(); 200 200 if (DISPLAY_VALUES[trimmed]) { ··· 203 203 return m; 204 204 }); 205 205 206 - // 5c: Fix property-specific and global values (data-driven from VALUE_FIXES) 206 + // Fix property-specific and global values (data-driven from VALUE_FIXES) 207 207 fixed = fixPropertyValues(fixed); 208 208 209 - // 5d: Fix 4-arg rgb/hsl -> rgba/hsla (#22) 209 + // Fix 4-arg rgb/hsl -> rgba/hsla (#22) 210 210 fixed = fixed.replace(/\brgb\s*\(\s*([^,)]+)\s*,\s*([^,)]+)\s*,\s*([^,)]+)\s*,\s*([^,)]+)\s*\)/g, "rgba($1, $2, $3, $4)"); 211 211 fixed = fixed.replace(/\bhsl\s*\(\s*([^,)]+)\s*,\s*([^,)]+)\s*,\s*([^,)]+)\s*,\s*([^,)]+)\s*\)/g, "hsla($1, $2, $3, $4)"); 212 212 213 - // 5e: Fix span(N) -> span N in grid properties (#43) 213 + // Fix span(N) -> span N in grid properties (#43) 214 214 fixed = fixed.replace(/\bspan\s*\(\s*(\d+)\s*\)/g, "span $1"); 215 215 216 - // 5f: Fix fr units in flex shorthand (#35) 216 + // Fix fr units in flex shorthand (#35) 217 217 fixed = fixed.replace(/flex\s*:\s*([^;!}]+)/g, function (m, flexVals) { 218 218 return "flex: " + flexVals.replace(/(\d+(?:\.\d+)?)fr/g, "$1"); 219 219 }); 220 220 221 - // 5g: Fix shorthand defaults (#8) 221 + // Fix shorthand defaults (#8) 222 222 if (opts.fixShorthandDefaults) { 223 223 fixed = fixShorthandValues(fixed); 224 224 } 225 225 226 - // 5h: Fix axis order for 2-value properties (#9) 226 + // Fix axis order for 2-value properties (#9) 227 227 if (opts.fixAxisOrder) { 228 228 fixed = fixAxisOrder(fixed); 229 229 } 230 230 231 - // 5i: Fix CCW -> CW for 4-value shorthands (#11, opt-in) 231 + // Fix CCW -> CW for 4-value shorthands (#11, opt-in) 232 232 fixed = fixShorthandDirection(fixed, opts); 233 233 234 234 return "{" + fixed + "}"; 235 235 }); 236 236 237 - // Phase 6: Restore comments 237 + // Restore comments 238 238 result = result.replace(/CMT(\d+)/g, function (match, index) { 239 239 return comments[parseInt(index, 10)]; 240 240 }); 241 241 242 - // Phase 7: Restore strings 242 + // Restore strings 243 243 result = result.replace(/STR(\d+)/g, function (match, index) { 244 244 return strings[parseInt(index, 10)]; 245 245 });
+1 -1
test/test.js
··· 60 60 test("#36 display-type -> display", function () { 61 61 var result = fixCSS(".x { display-type: flex; }"); 62 62 assertContains(result, "display:"); 63 - // Should not have "display-type" 63 + // Should not have 'display-type' 64 64 assertEqual(result.indexOf("display-type"), -1, "display-type should be removed"); 65 65 }); 66 66