CSS Classes vs. Inline Styles (Web Specs)
Use CSS classes for styles that repeat, belong to a component, or may need to change across a site. Use an inline style attribute for a genuinely unique value, often one set by code at runtime. Both are valid ways to style HTML, but they behave differently in the cascade and under site security rules.
Choosing between the two can feel like a small detail until a page needs a redesign or a bug appears on one screen. I use a simple test: will this presentation rule apply elsewhere, or might it need to change as part of a broader update? The answer usually points to a class. A one-off, calculated value may call for inline styling instead.
There is no rule that makes inline styles always wrong or inaccessible. The goal is to choose the method that makes the page clear, easier to maintain, and compatible with the project’s accessibility and security needs.
CSS classes and inline styles: purpose, scope, and use cases
A class is a reusable label on an HTML element, such as class="notice", that a stylesheet can select. An inline style is a set of CSS declarations placed in an element’s style attribute. Both can set presentation, but classes make sharing and central changes easier.
For example, a stylesheet can define a shared button:
<button class="button button-primary">Save</button>
.button {
padding: 0.75rem 1rem;
border: 0;
border-radius: 0.25rem;
}
.button-primary {
color: white;
background: #174ea6;
}
The same classes can go on several buttons. If the team changes the padding, it can update one rule. By contrast, this style applies directly to one button:
<button style="background-color: #174ea6; color: white">Save</button>
A class can be shared by many elements and selected by CSS. An inline declaration is attached to the element that carries it. You can write one inline value on each of several elements, but those declarations are separate and do not form one reusable rule.
| Situation | Usually the better fit | Why |
|---|---|---|
| A style is shared by several elements | CSS class | One rule can serve many elements |
| A component has a consistent visual design | CSS class | The component’s rules stay together |
| A value is calculated for one element at runtime | Inline style may fit | The value can be set as it changes |
| A one-off value is fixed in the page | Usually a class | A named rule is easier to review and revise |
| A site’s security policy restricts style attributes | Class in an allowed stylesheet | The policy may block inline style attributes |
Treat the table as a starting point, not a ban. A unique value can still be put in a class, and a runtime value can sometimes be represented by a class if the possible states are known. Choose the clearest option for the actual requirement.
HTML and CSS requirements: cascade, reuse, and implementation
The HTML Living Standard defines class and style as global attributes: they may be used on HTML elements. CSS then determines how declarations apply. The key practical difference is scope: classes let stylesheets match elements by label, while inline declarations sit on an individual element.
Start by deciding whether a style is shared, component-specific, or unique to one element. For shared presentation, write a descriptive class in an external or component-scoped stylesheet. Keep the class name tied to meaning or a component role, such as .notice-error, rather than a temporary appearance like .red-text.
<p class="notice-error">Your session has expired.</p>
.notice-error {
color: #8b1e1e;
border-inline-start: 0.25rem solid currentColor;
padding: 0.75rem;
}
If a script must set a one-off value, make the reason clear. For instance, a chart may receive a computed color or position. A CSS custom property can keep the stylesheet responsible for the design while the script supplies the changing value:
<div class="bar" style="--bar-size: 62%"></div>
.bar {
width: var(--bar-size);
}
This is still an inline style attribute, so check the site’s policy. If the value can be represented with a small set of named states, toggling classes may be simpler and easier to test.
How the cascade affects your choice
The cascade decides which CSS declaration wins when several declarations set the same property. Inline declarations generally outrank normal author stylesheet rules for that property. That can make them harder to override during a redesign or in a component state.
This does not mean inline styles always win. Importance, origin, and other cascade rules matter; an !important declaration in a stylesheet can override a normal inline declaration. But adding !important as a routine fix often hides the underlying conflict. Instead, inspect the matched rules in browser developer tools, then adjust the right class or component rule.
| Property set in both places | Typical result | Useful check |
|---|---|---|
| Normal class rule and normal inline declaration | Inline declaration wins | Inspect the element’s computed styles |
| Important stylesheet rule and normal inline declaration | Important rule wins | Check importance and cascade origin |
| Different properties in class and inline style | Both may apply | Review the final computed style for each property |
The CSS Cascading and Inheritance Level 5 specification describes the cascade, including how declarations are compared. Don’t infer the winner just from where a rule appears in a file; inspect the browser’s computed-style panel when results surprise you.
Accessibility, maintainability, and testing practices
Neither a class nor an inline style guarantees an accessible result. Accessibility depends on what the style does and how the page works. A color change, for example, should not be the only way to communicate an error. Check contrast, text legibility, keyboard focus, and behavior at different screen sizes.
WCAG 2.2 Level AA provides success criteria for accessible web content. Styling choices can affect whether a page meets them. Test the page itself, not just the CSS syntax: confirm that users can identify important states, follow focus as they tab, and read content when text size or spacing changes.
For maintainability, repeated inline declarations are a warning sign. They can make a single design change require edits in many places. If several elements have the same declarations, move them into a class and apply that class consistently. If inline values are truly data-driven, keep the shared visual rules in CSS and limit the inline part to the changing value.
Content Security Policy (CSP) is also worth checking. A site’s policy can restrict inline style attributes, depending on its directives and configuration. If the browser blocks a style, review the policy and console message rather than assuming the CSS property is invalid. A class in an approved stylesheet may be the right fix, but policy requirements vary by site.
A practical validation pass:
- Check the computed styles for unexpected overrides.
- Test the layout at narrow and wide viewport sizes.
- Navigate with a keyboard and confirm visible focus.
- Check text and interface contrast where applicable.
- Review browser errors and the site’s CSP.
- Search for repeated inline declarations and refactor shared patterns.
These checks help separate three issues that can look alike: a CSS cascade conflict, an accessibility problem, and a security policy block. Fix the cause rather than adding more declarations.
Implementation examples and production-quality outcomes
The examples below are worked scenarios, not reports from named companies. They show how the same decision process applies to common front-end tasks: reusable interface styles belong in classes, while truly variable values may need a different approach.
Scenario 1: A site-wide alert. Several pages show success and error messages. A class for each alert type keeps color, spacing, and border rules consistent. Adding the same style inline to every message would duplicate declarations and make a later redesign harder.
Scenario 2: A progress bar. The bar’s appearance is shared, but its width changes as progress changes. A class can define height, color, and transitions; code can provide the current width. Another option is toggling classes for fixed states, such as is-complete, if the design only needs a few states.
Scenario 3: A one-off spacing adjustment. A developer adds style="margin-top: 12px" to one element to fix a layout. If the value is permanent, a descriptive class is often easier to review and reuse. If it is a temporary test, remove it before the change is considered complete.
For a portfolio or production code review, the useful outcome is not simply “no inline styles.” It is being able to explain why the styling is shared or unique, how it behaves across states, and how you tested it. That reasoning is part of sound front-end practice.
A decision process for classes and inline styles
Use this short process each time you add a style. It keeps the decision tied to the job the code needs to do, rather than to a blanket rule. When in doubt, choose the option that makes the intent easiest for another developer to find and change.
- Identify the requirement. Is the style shared, component-specific, or unique to one element?
- Choose the scope. Put repeated or stable presentation in a class. Use inline styling only when a per-element value or runtime need justifies it.
- Check constraints. Review accessibility needs and any CSP rules that may affect style attributes.
- Test the result. Inspect computed styles, responsive behavior, keyboard access, and any console errors.
- Refactor repetition. If inline declarations spread across elements, move common rules into a stylesheet class.
A useful review question is: “If this design changes, where should the change happen?” If the answer is “in one shared rule,” use a class. If a script must update a unique value, keep that value limited and document its purpose.
Conclusion and FAQs
Classes are the usual choice for reusable, stable presentation because they make shared changes easier. Inline styles remain useful for specific, per-element values, especially when code calculates them. Neither choice replaces testing: check the cascade, accessibility, responsiveness, and CSP before calling the work done.
Are inline styles valid HTML?
Yes. The HTML Living Standard defines the style attribute. A site’s CSP may still restrict its use.
Are CSS classes better than inline styles?
For shared or reusable presentation, classes are usually easier to maintain. Inline styles can suit unique or runtime-generated values.
Do inline styles always override CSS classes?
They generally outrank normal author stylesheet declarations for the same property. Cascade importance and origin can change the result.
Can I override an inline style with !important?
A stylesheet declaration marked !important can override a normal inline declaration. Avoid using this as a routine workaround.
Are inline styles bad for accessibility?
Not by themselves. The result must still meet relevant accessibility needs, such as readable contrast and visible keyboard focus.
Can a CSS class be used on multiple elements?
Yes. Add the same class name to multiple elements, then define its rules in a stylesheet.
When are inline styles useful?
They can be useful when a script supplies a value that changes per element, such as a computed size or position.
Can CSP block a style attribute?
Yes. A site’s Content Security Policy may restrict inline styles. Check the policy and browser console for details.
Should I use classes for every style?
No. Use classes for shared and stable rules, but a genuine one-off or runtime value may justify inline styling.
How do I find why a style is not applying?
Inspect the element’s computed styles in browser developer tools. Look for overridden declarations, invalid values, and CSP errors.
(This article was written by one of our staff writers, Andrew Kensington. Visit our Meet the Team page.)
