How to choose where to put CSS in SGEN
The short answer
Three places. Pick by scope:
| Where | Scope | When to use |
|---|---|---|
| Custom CSS (the admin → Appearance → Custom CSS) | Site-wide design system | Tokens, base typography, brand-level utilities |
| SGB Additional CSS (SG-Builder → page-level CSS panel) | Single page | Layout tweaks, page-specific component overrides |
| Custom Codes (the admin → Tools → Custom Codes) | Last resort, head/body injection | Tracking scripts, third-party widgets, behavior the design system can't reach |
Default to Custom CSS. Drop to SGB Additional CSS when the rule is page-specific. Only reach for Custom Codes when neither of the first two will do the job.
What is this for?
SGEN exposes three places to add CSS. They look interchangeable on the surface — three "where do I put CSS" affordances — but they have very different scopes, cascade priorities, and gotchas. Picking the wrong one creates problems that surface later:
- CSS that "doesn't take effect" because it's being overridden by something else
- Style rules that disappear when a page is set as the homepage (slug class strips)
- Rules duplicated across pages that should have been in the design system
- Styles that survive page rebuilds (unintentionally) because they're at the wrong layer
This page is the decision rule.
Good use cases
- You're starting a new site and laying out your design system.
- You inherited a site where CSS is scattered across all three surfaces and you want to consolidate.
- You're hitting a "my CSS won't override" cascade fight and need to know which layer wins.
- You're documenting your team's CSS conventions.
Example 1: New site launch. The team defines --brand-espresso: #3b2010 and --brand-cream: #f5f0e8 as CSS custom properties in Custom CSS. Every page inherits these. The Brewing Guide landing page adds a single page-specific hero tint in its SGB Additional CSS — 4 lines, no effect on other pages.
Example 2: Inherited scattered site. Custom CSS has 2,400 lines with page-specific tweaks buried inside. The team extracts the 14 page-specific blocks to each page's SGB Additional CSS, reducing Custom CSS to 380 lines of clean design-system rules.
Example 3: Cascade fight. A button style isn't applying. Walking the cascade order reveals the SGB inline style set via the builder controls is overriding Custom CSS. Resetting via the component's style panel resolves it without touching Custom CSS.
What NOT to use this for
- Don't reach for Custom Codes to set body color. That's a design system job.
- Don't put per-page layout tweaks in Custom CSS. That clutters the global system with one-off rules.
- Don't paste tracking scripts into Custom CSS. That's what Custom Codes is for; Custom CSS is style-only.
How this connects to other features
- SG-Builder — the editor surface where SGB Additional CSS lives (per-page panel)
- Custom Codes — scripts and tracking go here, not Custom CSS
- Theme settings — base colors and typography ship from the theme; Custom CSS overrides come after
- URL slug strategy — the
body.page_id-<n>selector pattern used for page-scoped overrides in Custom CSS
Before you start
- Know which pages on your site need page-specific styles vs which use site-wide rules.
- Have the page IDs ready for any
body.page_id-<n>selectors (the admin → Pages → the page row shows the numeric ID in the edit URL). - If consolidating a messy site, open all three surfaces first so you have a mental map before moving any rules.
Where to find it
- Custom CSS: the admin → Appearance → Custom CSS
- SGB Additional CSS: open the page in SG-Builder → Settings (gear icon) → Additional CSS
- Custom Codes: the admin → Tools → Custom Codes
The three layers, in detail
1. Custom CSS — design system tier
Location: the admin → Appearance → Custom CSS
Cascade priority: loads after the theme + before page-level styles.
Use for:
- CSS custom properties / design tokens (
--brand-blue,--text-base,--space-md) - Base element styles (
body,h1–h6,p,a,button) - Site-wide utilities (
.text-center,.btn-primary,.card) - Component-level styles for reusable patterns
Scoping: site-wide by default. Use body.page_id-<n> (NOT body.page-<slug> — slug class disappears on homepage) for page-specific overrides at the global level. But for true page-specific work, prefer SGB Additional CSS.
2. SGB Additional CSS — page-level tier
Location: SG-Builder editor → Settings → Additional CSS (per-page panel)
Cascade priority: loads after Custom CSS — wins specificity ties.
Use for:
- Layout tweaks unique to this page
- One-off color overrides for a campaign page
- Component variants that shouldn't bleed to other pages
- Custom hover states for this page's hero section
Scoping: automatically scoped to the page. No need to wrap in body selectors.
3. Custom Codes — last resort
Location: the admin → Tools → Custom Codes
Cascade priority: wherever you inject (head/body, before/after).
Use for:
- Tracking scripts (GA4, Meta Pixel, custom analytics)
- Third-party widgets (chat, intercom, calendly embeds)
- Tag manager containers
- HTML structure the builder doesn't expose (rare)
- CSS only as an emergency override when the design system can't reach
Why "last resort": Custom Codes inject raw HTML/JS/CSS at the page chrome level. They're harder to audit, easier to forget about, and can't be re-themed cleanly. If you're putting CSS here, ask first: can this live in Custom CSS or SGB Additional CSS?
The cascade order
When the same property gets set at multiple layers, SGEN resolves in this order (later wins):
- Theme defaults (lowest priority)
- Custom CSS (design system)
- SGB component inline styles (set via builder controls)
- SGB Additional CSS (page-level)
- Custom Codes (head injection — depends on placement)
!importantdeclarations (override everything — avoid)
If your CSS isn't applying, walk down this list and find what's overriding you. Usually the answer is "SGB inline styles set via the visual editor" — clear them via the builder's style reset.
Scope guide — pick by scope, not by habit
- Will this style apply to every page? → Custom CSS
- This page only (or this template)? → SGB Additional CSS
- Not a style — a script or third-party embed? → Custom Codes
- A behavior change (not visual)? → Custom Codes (or wait for the platform to expose it natively)
Common mistakes
Putting page-specific tweaks in Custom CSS
Symptom: Custom CSS file grows to 2000+ lines, hard to navigate, every change risks breaking a different page. Fix: extract page-scoped rules into the relevant page's SGB Additional CSS.
Putting design tokens in SGB Additional CSS
Symptom: same color hex repeated on every page; brand update means editing every page. Fix: define --brand-blue once in Custom CSS, reference via var(--brand-blue) everywhere.
Using Custom Codes for body color
Symptom: tracking scripts and style rules in the same file. Audit hell. Fix: Custom Codes is for scripts. Style rules move to Custom CSS.
body.page-<slug> selectors that vanish
Symptom: page-scoped rule works fine until the page is set as homepage, then breaks. Fix: use body.page_id-<n> (numeric ID, stable). Or use SGB Additional CSS (auto-scoped, no body selector needed).
Where to find it
- Custom CSS: the admin → Appearance → Custom CSS
- SGB Additional CSS: open the page in SG-Builder → Settings (gear icon) → Additional CSS
- Custom Codes: the admin → Tools → Custom Codes
Steps to consolidate a messy site
Steps
1. Inventory
Open all three surfaces (Custom CSS, SGB Additional CSS on your 5 most complex pages, Custom Codes). Note approximate line counts and scopes. Flag any rules that look page-specific inside Custom CSS or look like design tokens inside SGB Additional CSS.
2. Move design tokens up
Anything that defines colors, spacing, or typography moves to Custom CSS as CSS custom properties. Example:
/* === Design tokens === */:root {--brand-espresso: #3b2010;--brand-cream: #f5f0e8;--text-base: #1a1a1a;--space-md: 1.5rem;}3. Move base element styles up
body, h1–h6, p, a base rules move to Custom CSS. These are site-wide, not page-specific.
4. Move page-specific tweaks down
Anything that targets one page moves to that page's SGB Additional CSS. Open the page in SG-Builder → Settings → Additional CSS and paste the rules there.
5. Audit Custom Codes for CSS
Check Custom Codes for style blocks. Move style rules to Custom CSS. Keep Custom Codes for scripts and third-party embeds only.
6. Test representative pages
View 3-4 representative pages (homepage, a blog post, a product page, a contact page). Confirm visual parity before declaring the consolidation done.
After consolidation, one team reduced Custom CSS from 2,400 lines to 380 lines and SGB Additional CSS on their Brewing Guide landing from 0 lines (everything was wrong in Custom CSS) to 18 lines of page-specific tweaks.
What success looks like
- Custom CSS is your readable design system — variables on top, base styles in the middle, utilities at the bottom.
- Each page's SGB Additional CSS is short (under 50 lines typically) and obviously page-specific.
- Custom Codes contains tracking + third-party scripts only — no style rules.
- No
body.page-<slug>selectors anywhere — only stablebody.page_id-<n>selectors where page-scoping is needed in Custom CSS. - A new team member can open Custom CSS and understand the structure in under 5 minutes.
What to do if it does not work
"My CSS rule isn't applying." Walk the cascade order above. Usually the override is in SGB inline styles set via the builder UI — reset via the component's style panel.
"My page-scoped rule broke when I set the page as homepage." You used body.page-<slug>. Switch to body.page_id-<n> or move the rule to SGB Additional CSS.
"My Custom CSS file is 3000 lines and I'm afraid to touch it." Refactor incrementally. Add comments marking sections (/* === Design tokens === */). Move out anything that targets a specific page. Don't try to rewrite all at once.
"I moved a rule to SGB Additional CSS and it's not applying." SGB Additional CSS loads after Custom CSS — it should win specificity ties. Check that the selector is correct (no body class wrapping needed in SGB Additional CSS; it's already page-scoped).
"Custom Codes isn't loading my style block." Custom Codes injects into the page chrome. Placement (head/body, before/after content) matters. If the rule needs to override SGB styles, inject it at end-of-body or use head placement with adequate specificity.
Anti-pattern reference
The following patterns cause the most CSS confusion on SGEN sites. Each one has a clear fix.
| Anti-pattern | Symptom | Fix |
|---|---|---|
| Page-specific tweaks in Custom CSS | File grows to 2000+ lines; every change risks breaking another page | Extract to SGB Additional CSS on the relevant page |
| Design tokens in SGB Additional CSS | Same color hex repeated on every page; brand update = editing every page | Define --brand-blue once in Custom CSS; reference via var(--brand-blue) everywhere |
| CSS in Custom Codes | Tracking scripts and style rules in the same file; audit hell | Move style rules to Custom CSS; keep Custom Codes for scripts |
body.page-<slug> selectors | Page-scoped rule works until the page becomes the homepage; then breaks | Use body.page_id-<n> (stable numeric ID) or SGB Additional CSS |
!important everywhere | Cascade fights escalate; the next developer can't reason about specificity | Remove !important; fix specificity via correct layer instead |
| No section comments in Custom CSS | Can't find anything; afraid to delete old rules | Add /* === Design tokens === /, / === Base elements === /, / === Utilities === */ section headers |
Decision reference
Use this table when a new CSS need arises:
| Scenario | Right surface | Why |
|---|---|---|
| Brand color refresh | Custom CSS | Design tokens change site-wide |
| Hero tint for a campaign page | SGB Additional CSS | Scoped to one page, not the design system |
| GA4 tracking snippet | Custom Codes | Script injection, not styling |
| Custom button hover state (site-wide) | Custom CSS | Applies everywhere |
| Custom button hover state (one page) | SGB Additional CSS | Scoped, no body selector needed |
| Chat widget (Intercom, Crisp) | Custom Codes | Third-party script |
| Override SGB component default color | Custom CSS or SGB Additional CSS | Depends on whether it's site-wide or page-specific |
Worked example — CSS audit
A team launched their SGEN site with all CSS in Custom CSS. After six months, the file was 2,400 lines. Here's how they triaged it:
What they found:
- 380 lines of genuine design-system rules (tokens, base elements, utilities) — these stayed in Custom CSS
- 1,200 lines of page-specific tweaks for 14 different pages — these moved to each page's SGB Additional CSS
- 420 lines of theme-coupled selectors from a theme they'd already switched away from — these were deleted
- 400 lines of Custom Codes-style script insertion (a chat widget CSS override) — these moved to Custom Codes
Result:
- Custom CSS: 380 lines (readable, system-level)
- SGB Additional CSS per page: 10-40 lines each (obviously page-specific)
- Custom Codes: 25 lines (the chat widget override + GA4)
Total time for the audit: one afternoon. The site now has no cascade fights and no !important declarations.
CSS scoping patterns reference
When you need to target specific pages from Custom CSS (rare — prefer SGB Additional CSS), use these stable patterns:
/* Target a specific page by numeric ID — stable even if the page becomes the homepage */body.page_id-42.hero-section {background: var(--brand-espresso);}/* Target a post type (all blog posts) */body.single-post.post-content {max-width: 720px;}/* Target a category archive */body.category-recipes.archive-header {font-size: 2rem;}/* Target the homepage specifically — use page_id, not page-home */body.page_id-1.announcement-bar {display: block;}Never use body.page-<slug> for any page that might become the homepage — SGEN strips the slug class when a page is set as the homepage.
Related reading
- SG-Builder overview — where SGB Additional CSS lives
- URL slug strategy — the
body.page_id-<n>selector pattern - Switch SGEN theme safely — preserving Custom CSS across theme changes
