Cautions
Important cautions when using Atomic CSS. Understanding these helps prevent unexpected issues.
Dynamic Class Binding
Most common mistake
Atomic CSS statically scans source code to detect classes. Class names stored in JavaScript variables are not detected.
Cause
The Atomic CSS extension analyzes source code text at save time to find used class names and generates only the corresponding CSS. Since JavaScript is not executed, strings inside variables cannot be tracked.
Not detected
Dynamic binding via variables cannot detect classes.
<!-- ❌ Class in variable — CSS not generated -->
<script setup>
const boxStyle = "w100px h100px bg6366F1 br8px"
</script>
<div :class="boxStyle"></div>Detected
Class names that exist as literals in source code are properly detected.
<!-- ✅ Literal class — CSS generated normally -->
<div class="w100px h100px bg6366F1 br8px"></div>Dynamic Binding in Frameworks
The same issue occurs when dynamically binding classes in Vue, React, Svelte, etc.
Not detected
<!-- ❌ v-for + dynamic binding -->
<script setup>
const items = [
{ cls: "bg6366F1 br8px" },
{ cls: "bg34D399 br12px" },
]
</script>
<div v-for="item in items"
:class="item.cls">
</div>Detected
<!-- ✅ Conditionals also as full strings -->
<div :class="active
? 'bg6366F1 cFFFFFF'
: 'bg27272A c71717A'">
</div>
<!-- ✅ This way both class sets are
present as literals in source and detected -->String Concatenation Also Fails
Template literals or string concatenation to build class names are also not detected.
Not detected
// ❌ Class generated by string concatenation
const size = 16
const cls = `fs${size}px` // "fs16px"
// → No "fs16px" literal in source
// ❌ Class generated by function
function getBg(color) {
return `bg${color}`
}
getBg("FF0000") // "bgFF0000"
// → No "bgFF0000" literal in sourceDetected
// ✅ Use full class names as literals
const cls = isLarge ? 'fs2rem' : 'fs1-4rem'
// → Both 'fs2rem' and 'fs1-4rem' are detected
// ✅ List as literals in map object
const sizeMap = {
sm: 'fs1-2rem p8px',
md: 'fs1-4rem p12px',
lg: 'fs1-6rem p16px',
}
// → All values exist as literals and are detectedCore Principle
The complete class name string must exist as-is somewhere in the source code. Concatenation, splitting, and variable references are not detected.
Class Name Conflicts
Atomic CSS creates class names from the initials of CSS properties, so different properties may share the same abbreviation. They are differentiated by presence of units.
| Class | CSS | Differentiation |
|---|---|---|
fs0 | flex-shrink: 0 | No unit → flex-shrink |
fs16px | font-size: 16px | With unit → font-size |
fs1-4rem | font-size: 1.4rem | With unit → font-size |
br8px | border-radius: 8px | With unit → border-radius |
br0 | border-radius: 0 | border-radius reset |
brn | border-right: 0 | border-right removal |
When in doubt
Use autocomplete. When you type a class name, the hover preview immediately shows what CSS will be generated. When unsure, verify instead of guessing.
Missing Units
Properties that use numeric values must include units. Without units, they may be interpreted as different properties or not work at all.
No unit — unintended result
fs16 | Does not work (unit required) |
w100 | Does not work (unit required) |
gap10 | Does not work (unit required) |
br0 | border-radius: 0 |
With unit — correct result
fs16px | font-size: 16px |
w100px | width: 100px |
gap10px | gap: 10px |
br0 | border-radius: 0 |
Unit rules summary
px— Pixels:w100px,gap8pxrem— 1rem=10px:w10rem(100px),gap2rem(20px)p— Percent:w50p(50%),w100p(100%)vh/vw— Viewport:h100vh,w100vw
CSS Cascade Order (Specificity)
All Atomic CSS classes have the same selector specificity (single class). When multiple classes target the same property, the one declared later in the CSS file takes effect. This is not determined by order in the HTML class attribute.
<!-- ⚠️ Which applies, w100px or w200px? -->
<div class="w100px w200px bg18181B p16px">
Determined by declaration order in CSS file
(Not by order in HTML class attribute)
</div>
<!-- ✅ Use only one class per property -->
<div class="w200px bg18181B p16px">
Specify only one clearly
</div>Caution
Using duplicate classes for the same property makes it hard to predict which one applies. Use only one class per property per element.
When you intentionally need to raise priority, use the i suffix which adds !important.
<!-- Add !important with i suffix -->
<div class="w100pxi bg6366F1 p16px">
width: 100px !important
</div>
<!-- Override external library styles -->
<div class="external-component df jcc aici">
Force layout with display: flex !important
</div>Do not abuse !important
Use the i suffix only when truly necessary, such as overriding external library styles. Avoid using it for regular styling.
rem Base Value
Atomic CSS rem units are designed based on html { font-size: 10px }, meaning 1rem = 10px. Without this setting, rem values will not match their intended sizes.
Without base value (1rem = 16px)
fs1-6rem | Intended: 16px, Actual: 25.6px |
gap2rem | Intended: 20px, Actual: 32px |
w24rem | Intended: 240px, Actual: 384px |
With base value (1rem = 10px)
fs1-6rem | 16px correct |
gap2rem | 20px correct |
w24rem | 240px correct |
Add the following to your project's global CSS:
html {
font-size: 10px;
}
/* Now rem calculations are intuitive */
/* 1.6rem = 16px */
/* 2rem = 20px */
/* 2.4rem = 24px */
/* 10rem = 100px */Not using rem?
If you only use px values, this setting is not required. However, rem is recommended as it allows concise expression of values 20px and above.
Hyphen (-) Interpretation
Hyphens are interpreted differently depending on context. Understanding hyphen roles is essential to prevent unintended results.
| Usage | Example | Interpretation |
|---|---|---|
| Decimal point | gap1-5rem | gap: 1.5rem (15px) |
| Decimal point | fs1-4rem | font-size: 1.4rem (14px) |
| Value separator | gtc1fr-2fr-1fr | grid-template-columns: 1fr 2fr 1fr |
| Value separator | flex1-1-auto | flex: 1 1 auto |
| Media query | sm-dn | @media (max-width: 768px) { display: none } |
| Pseudo-class | hover-bgFF0000 | :hover { background-color: #FF0000 } |
| Negative | neg-mt10px | margin-top: -10px |
Watch for confusion
gap1-5rem means 1.5rem, not 1rem and 5rem. Whether a hyphen represents a decimal point or value separator is determined by the following unit.
Do Not Edit Generated CSS Files
Do not directly edit CSS files auto-generated by the Atomic CSS extension (such as atomic.css). The extension re-scans and overwrites the content on every file save.
Do not
- Directly adding styles to atomic.css
- Modifying/deleting classes in atomic.css
- Defining custom classes in atomic.css
Correct approach
- Write global resets/fonts in a separate CSS file
- Adding Atomic classes in HTML auto-generates the CSS
- Removing classes from HTML also removes them from CSS
Checklist
Check the following when using Atomic CSS.
Does the class name exist as a literal string in the source code?
Do numeric classes include units (px, rem, p, vh)?
Is html { font-size: 10px } set? (when using rem)
Are you not duplicating classes for the same property?
Have you avoided manually editing auto-generated CSS files?
Have you verified confusing classes with autocomplete preview?