-
Notifications
You must be signed in to change notification settings - Fork 7
Styling
Summary: This guide explains StartER's unopinionated 3-tier CSS strategy, from semantic styling with Pico CSS via CDN to component-scoped CSS and custom framework setup.
What you'll learn:
- Understand StartER's unopinionated, classless CSS philosophy
- Customize brand styling using Pico CSS variables in
src/react/index.css - Add component-scoped CSS files with Vite
- Configure Tailwind CSS or custom CSS frameworks if desired
StartER is deliberately unopinionated about CSS. Instead of locking you into a complex CSS framework (like Tailwind, Sass, or CSS-in-JS), StartER provides a 3-tier styling strategy that starts with zero configuration and grows with your project needs.
┌───────────────────────────────────────────────────────────────────────────┐
│ Tier 1: Semantic HTML (Pico CSS via CDN in index.html) │
│ └── Automatic styling for <article>, <header>, <nav>, <button>, etc. │
├───────────────────────────────────────────────────────────────────────────┤
│ Tier 2: Global Theme Customization (src/react/index.css) │
│ └── Override CSS variables like --pico-primary, --pico-font-family │
├───────────────────────────────────────────────────────────────────────────┤
│ Tier 3: Component-Scoped CSS (Vite native CSS imports) │
│ └── Import component-specific styles directly (import "./ItemCard.css") │
└───────────────────────────────────────────────────────────────────────────┘
StartER includes Pico CSS via CDN in index.html. Pico is a classless CSS framework: it automatically styles standard HTML5 semantic elements without requiring utility classes.
Simply write standard HTML tags in your React components:
function ItemCard({ title, content }: { title: string; content: string }) {
return (
<article>
<header>
<h3>{title}</h3>
</header>
<p>{content}</p>
<footer>
<button type="button">Read more</button>
</footer>
</article>
);
}Pico will automatically render this with clean padding, typography, card borders, and interactive hover states.
-
Layout & Structure:
<header>,<main>,<footer>,<nav>,<article>,<aside>,<section> -
Forms & Inputs:
<form>,<input>,<select>,<textarea>,<button>,<fieldset>,<label> -
Dialogs & Modals:
<dialog> -
Tables & Lists:
<table>,<ul>,<ol>,<dl>
To change your application's brand color, font, or border radius, edit src/react/index.css.
Pico CSS uses native CSS variables on the :root selector:
/* src/react/index.css */
:root {
/* Brand primary color (buttons, active links, accents) */
--pico-primary: #6366f1;
--pico-primary-background: #6366f1;
--pico-primary-underline: rgba(99, 102, 241, 0.5);
/* Typography */
--pico-font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
/* Geometry */
--pico-border-radius: 0.5rem;
}Tip
Consult the Pico CSS Color Palette Documentation for the full list of customizable CSS variables.
Pico CSS supports dark mode out of the box with zero extra configuration.
By default, Pico automatically detects and matches the user's operating system dark/light mode preference (prefers-color-scheme).
To force a specific theme globally, set the data-theme attribute on the <html> element in index.html:
<!-- Force dark mode -->
<html data-theme="dark">
<!-- Force light mode -->
<html data-theme="light">To allow users to switch themes dynamically in React:
export function ThemeToggle() {
const toggle = () => {
const html = document.documentElement;
const current = html.getAttribute("data-theme");
html.setAttribute("data-theme", current === "dark" ? "light" : "dark");
};
return (
<button type="button" onClick={toggle} className="secondary outline">
Toggle Theme
</button>
);
}When a specific React component requires custom styling beyond what Pico provides, create a .css file next to your component. Vite natively supports importing CSS files inside React components without any extra configuration.
- Create
src/react/components/item/ItemCard.css:
.item-badge {
display: inline-block;
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
font-weight: 600;
color: var(--pico-primary-inverse);
background-color: var(--pico-primary);
border-radius: var(--pico-border-radius);
}- Import it in
src/react/components/item/ItemCard.tsx:
import "./ItemCard.css";
export function ItemCard() {
return <span className="item-badge">Featured</span>;
}If you prefer utility-first CSS with Tailwind CSS, you can install it in a few seconds thanks to Vite:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/react/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};Replace src/react/index.css with:
@tailwind base;
@tailwind components;
@tailwind utilities;Vite will automatically compile Tailwind CSS during development and production builds.
AI co-creation
Getting started
Explanations
How-To Guides
Reference
Digging deeper