Styling

By Syncfusion®, Inc. · Last updated

Scoped styles and how scoping works, styling child components, :global() and is:global, global stylesheets in a layout, CSS order, inline styles, define:vars, styling with props, CSS imports, Tailwind CSS, Sass, PostCSS, CSS Modules, bundling and inlineStylesheets.

Styling in Astro

  • Astro uses plain CSS. You do not need to learn a new styling language.
  • You can write CSS inside a component, in a separate file, or with tools like Tailwind CSS.
  • By default, a component's CSS only styles that component.
  • In this lesson, you will style Asha's site and learn when styles stay local and when they go global.

Simple lesson: CSS in an Astro component styles only that component, unless you ask for more.

A Real-World Example

  • Asha's post cards have h2 titles. Her page also has an h2 for "Contact".
  • She makes card titles purple with h2 { color: purple; } inside PostCard.astro.
  • In plain HTML, that rule would turn every h2 on the page purple.
  • In Astro, only the card titles turn purple. The "Contact" heading stays black.

Press ▶ Run. Only the card heading is purple.

What happened:

  • The <style> tag is inside PostCard.astro.
  • Its h2 rule reached the card's heading, but not the page's "Contact" heading.
  • Open HTML sent to browser. The card's tags carry an extra attribute, such as data-astro-cid-....

What You Will Learn

In this lesson, you will learn:

  1. How scoped styles work, and why they are safe.
  2. How to style a child component or slotted content.
  3. How to add global styles, and where.
  4. How CSS order decides which rule wins.
  5. How to use values from the script in CSS.
  6. How to import CSS files and npm CSS.
  7. How Tailwind CSS, Sass, PostCSS and CSS Modules fit in.
  8. How Astro bundles your CSS for the browser.

Scoped Styles

style Tags in Components

  • Write a <style> tag anywhere in a component's template. Most people put it at the end.
  • Write normal CSS inside it.
  • Astro removes the tag from the HTML and puts the CSS in the page's stylesheet.

How Scoping Works

  • Scoped style = a rule that applies only to the component it is written in.
  • Astro adds a unique attribute, such as data-astro-cid-abc123, to every tag in the component.
  • It also adds that attribute to every selector in the component's CSS.
  • So h2 { ... } becomes h2[data-astro-cid-abc123] { ... }. It can only match that component's h2.

Animation: the rule h2 color purple gets a unique attribute added. It then matches only the h2 inside the card, not the h2 outside.

h2 color: purple;

h2[data-astro-cid-x1] ... Astro adds the component's ID

PostCard (has data-astro-cid-x1) Card title

Page (no x1 attribute) Contact

The rule gets the component's ID, so it only matches tags with that ID.

Scoped styles let you use short, simple selectors like h2 and p. They can never break another component.

Styling Child Components

  • Scoped styles stop at a component's edge.
  • A parent's p { } rule does not reach the <p> inside a child component.
  • Styles for a child belong in the child.
  • If the parent must decide a child's look, pass a prop or a class (see below).

Using :global()

  • :global() turns one selector back into a normal, unscoped selector.
  • Common use: style the HTML that arrives through a <slot />, or HTML from set:html.
  • Keep the scoped part in front, so the rule stays inside the component: .prose :global(a) { ... }.

Press ▶ Run. The link comes through the slot. Only :global() can style it.

  • Only the link inside .prose is orange.
  • Without :global(), the rule would match nothing, because the link carries the page's ID.

Simple lesson: styles are scoped by default. Use :global() for one selector that must reach in.

Global Styles

is:global

  • <style is:global> turns off scoping for the whole tag.
  • Every rule in it styles the whole page, like a normal stylesheet.
  • Use it rarely. Prefer a global CSS file.

A component with is:global styles changes every page it appears on. A rule like h1 { color: red } there can surprise you far away from the component.

Importing a Global Stylesheet

  • Put site-wide CSS in a file, such as src/styles/global.css.
  • Import it in a component's script: import "../styles/global.css";.
  • Astro adds it to every page that uses that component.

Global Styles in a Layout

  • The best place for the import is your base layout.
  • Every page uses the layout, so every page gets the global CSS.
  • Put fonts, colours, body spacing and basic link styles there.

CSS Order and the Cascade

  • Cascade = the browser's rules for picking a winner when two CSS rules clash.
  • A more specific selector wins. h2[data-astro-cid-x1] is more specific than h2.
  • So a component's scoped rule usually beats a global rule for the same tag.
  • When two rules are equally specific, the one loaded later wins.

Press ▶ Run. The global file sets the body. The component's scoped h1 rule beats the global h1 rule.

Simple lesson: put global CSS in a file and import it in the base layout. Scoped rules usually win over global ones.

Dynamic Styles

Inline Styles

  • You can still write style="..." on a tag.
  • Astro also accepts an object: style={{ color: accent, fontSize: "1.2rem" }}.
  • Use inline styles for one-off values. Use classes for anything repeated.
  • The bar's width comes from progress. Change it to 90 and run again.
  • In the object form, CSS names are written in camelCase: borderRadius, not border-radius.

define:vars in style

  • define:vars passes variables from the script into a <style> tag.
  • Write <style define:vars={{ accent }}>. Inside, use var(--accent).
  • Astro turns each variable into a CSS custom property on the component.

Styling with Props

  • Combine props and define:vars to let the parent choose a colour.
  • Or combine props and class:list to switch between ready-made classes.
  • Each badge gets its own --color value.
  • size picks the small or large class.

Simple lesson: define:vars sends script values into CSS. Props let the parent choose them.

CSS Imports and Tools

Importing CSS Files

  • import "../styles/global.css"; in a script adds the file to the page.
  • Astro bundles it with the rest of your CSS.

Importing CSS from npm Packages

  • Some packages ship CSS. Import it by its package path:
---
import "open-props/style";
---

Linking Stylesheets from public/

  • A file in public/ can be linked with a normal tag: <link rel="stylesheet" href="/theme.css" />.
  • Astro does not process or shrink it. Use this only for files that must stay as they are.

Adding Tailwind CSS

  • Tailwind CSS = a tool where you style with small classes, such as text-xl and p-4.
  • Add it with one command:
npx astro add tailwind
  • It installs Tailwind, adds its Vite plugin to the config and creates src/styles/global.css with @import "tailwindcss";.
  • Import that file in your layout. Then use classes: <h1 class="text-3xl font-bold">.

Sass, Less and Stylus

  • Sass = CSS with extra features, such as variables and nesting.
  • Install it: npm install sass. Then write <style lang="scss">.
  • Less and Stylus work the same way: install the package, then use lang="less" or lang="styl".

PostCSS

  • PostCSS = a tool that changes CSS with plugins, such as adding browser prefixes.
  • Astro runs it already. Add a postcss.config.cjs file to add plugins.

CSS Modules

  • CSS Module = a .module.css file whose class names are made unique.
  • Import it as an object: import styles from "./Card.module.css";.
  • Use it: <div class={styles.card}>.
  • Most Astro projects do not need them, because <style> is already scoped.

In this lab, .css imports and <style> tags work. Tailwind, Sass and CSS Modules need npm packages, so try them on your own computer.

Simple lesson: plain CSS covers most needs. Add Tailwind or Sass with one install when you want them.

Style Output

Bundling and Minification

  • Bundling = joining many CSS pieces into a few files.
  • Minification = removing spaces and comments so files are smaller.
  • astro build does both. Each page gets only the CSS of the components it uses.

Inlining Stylesheets

  • Inline stylesheet = CSS placed inside a <style> tag in the HTML, instead of a separate .css file.
  • Small CSS loads faster inline, because the browser makes no extra request.
  • build.inlineStylesheets in the config decides:

    • "auto" (the default) = inline small stylesheets, link big ones.
    • "always" = inline all of them.
    • "never" = always use separate .css files.

Simple lesson: Astro bundles, shrinks and sends each page only the CSS it needs.

TL;DR

  1. Scoped style = <style> in a component. Only styles that component.
  2. How = Astro adds a data-astro-cid-... attribute to tags and selectors.
  3. :global(sel) = one unscoped selector. Use it for slotted or set:html content.
  4. is:global = the whole <style> tag is unscoped.
  5. Global CSS = a file imported in the base layout.
  6. Cascade = more specific wins. Scoped rules usually beat global ones.
  7. define:vars = script values as CSS variables.
  8. Tools:

    • Tailwind = npx astro add tailwind,
    • Sass = npm install sass + lang="scss",
    • CSS Modules = *.module.css.
  9. inlineStylesheets = auto, always or never.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
Styling a child's tags from the parentParent CSS reaches everythingStyle inside the child, or use a propNothing changes
Styling slotted HTML without :global()Slot content has the component's IDUse .wrapper :global(a)The rule matches nothing
Using is:global everywhereGlobal is simplerUse a global CSS file, and keep components scopedStyles clash across the site
Global CSS imported on one page onlyImports affect every pageImport it in the base layoutOther pages look unstyled
color: accent in CSS with define:varsThe variable name works as isWrite var(--accent)The colour is ignored
<link href="/src/styles/global.css">src files are servedImport src CSS in a scriptThe file is not found

Check Yourself

Exercises

What to Remember

  • A <style> in a component is scoped to that component.
  • Use :global() for slotted or set:html content.
  • Import global CSS in the base layout.
  • define:vars and props let the parent choose styles.
  • Tailwind and Sass are one install away. Astro bundles and shrinks all CSS.

Next: Client-Side Scripts, where Asha adds the first interactive features.