Skip to main content
RapidDev - Software Development Agency
weweb-tutorial

WeWeb Custom CSS: Classes, Fonts, Animations, and Themes

WeWeb has three CSS injection points: per-element Custom CSS field in the Styling panel, global CSS via App Settings → Custom Code → Head, and the CSS classes system for reusable styles. Custom fonts load from the project dashboard Fonts section or via Google Fonts link in the Head. CSS animations are configured in Styling panel → Animations with keyframe editor. Important: custom CSS does not render in editor preview — publish to see it applied.

What you'll learn

  • How to create and manage reusable CSS classes with subclasses for hover, focus, and active states
  • How to apply per-element Custom CSS and global project-level CSS styles
  • How to upload custom fonts (TTF/WOFF2) and use Google Fonts in your WeWeb project
  • How to create CSS keyframe animations and transitions using the Styling panel → Animations tab
  • The correct injection point for each CSS method and why custom CSS doesn't appear in editor preview
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read30-40 minWeWeb Free plan and aboveMarch 2026RapidDev Engineering Team
TL;DR

WeWeb has three CSS injection points: per-element Custom CSS field in the Styling panel, global CSS via App Settings → Custom Code → Head, and the CSS classes system for reusable styles. Custom fonts load from the project dashboard Fonts section or via Google Fonts link in the Head. CSS animations are configured in Styling panel → Animations with keyframe editor. Important: custom CSS does not render in editor preview — publish to see it applied.

WeWeb Custom CSS: Classes, Fonts, Animations, and Global Styles

WeWeb's visual Styling panel covers the vast majority of CSS you need — spacing, colors, flexbox, typography, borders, shadows, and more. But when you need custom scroll behavior, pseudo-element styles, keyframe animations beyond the built-in presets, or precise control over third-party component styles, you need to write CSS directly. WeWeb offers three pathways: the per-element Custom CSS field for element-specific rules, the CSS classes system for reusable styles you can apply across multiple elements, and the global head injection in App Settings → Custom Code for project-wide styles. This tutorial covers all three pathways, plus custom fonts and animation configuration.

Prerequisites

  • A WeWeb project with at least one page and some elements to style
  • Basic CSS knowledge (selectors, properties, pseudo-classes, keyframes)
  • Understanding of WeWeb's Styling panel (the panel that appears on the right when you select an element)

Step-by-step guide

1

Create a reusable CSS class in the Styling panel

WeWeb's CSS classes system lets you define a set of styles once and apply them to multiple elements. To create a class: select any element in the editor → open the Styling panel on the right → at the top of the panel, find the Classes section (it shows the element's current classes). Click the + icon or the Add class field. Type a new class name (e.g., 'card-shadow', 'primary-button') and press Enter. The class is created and applied to the selected element. Now any styles you set in the Styling panel while this class is active are stored in that class — not on the element directly. To apply the same class to another element, select the other element → click the Classes field → type or search for your class name → select it. Changes to the class automatically apply everywhere it is used.

Expected result: A named CSS class is created and applied to an element. The class appears in the Classes section at the top of the Styling panel.

2

Add subclasses for interactive states (hover, focus, active)

Subclasses in WeWeb are CSS pseudo-classes applied to a base class. They let you define how an element looks when hovered, focused, or in another state without writing custom CSS. To add a subclass: select an element with a class applied → in the Styling panel Classes section, click the dropdown arrow next to your class name → select Add subclass → choose from hover, focus, active, disabled, or custom. With the hover subclass active, any style changes you make in the Styling panel are stored as hover styles. For example, change the background color — it will only apply when the user's cursor is over the element. WeWeb renders subclasses as CSS like .my-class:hover { background-color: ... }. The cascade works from top to bottom: bottom classes (and their subclasses) override upper classes.

Expected result: Hovering over the element applies the subclass styles, and the base class styles apply when not hovering.

3

Add per-element Custom CSS for advanced selectors

When you need CSS that the Styling panel cannot visually configure — pseudo-elements (::before, ::after), child selectors, complex combinators, or overrides for third-party component internals — use the per-element Custom CSS field. Select your element → scroll to the very bottom of the Styling panel → find the Custom CSS section → click the text area to expand it. Write CSS relative to the element's root: use a period followed by nothing for the element itself, or descendant selectors for child elements. WeWeb wraps your CSS with the element's unique class automatically, so your rules are scoped to this element instance. Do not include the element's own class in your selectors — WeWeb adds it for you.

typescript
1/* Per-element Custom CSS field — Styling panel → Custom CSS section */
2/* No need to prefix with the element's class — WeWeb scopes it automatically */
3
4/* Style the placeholder text in an input */
5::placeholder {
6 color: #9ca3af;
7 font-style: italic;
8}
9
10/* Style paragraphs inside this text element */
11p {
12 margin-bottom: 1rem;
13 line-height: 1.7;
14}
15
16/* Create a gradient underline effect */
17&::after {
18 content: '';
19 display: block;
20 height: 2px;
21 background: linear-gradient(90deg, #3b82f6, #8b5cf6);
22 margin-top: 4px;
23 border-radius: 1px;
24}
25
26/* Responsive override for this specific element */
27@media (max-width: 767px) {
28 font-size: 14px;
29 padding: 8px 12px;
30}

Expected result: After publishing, the element displays the custom CSS rules including pseudo-elements and responsive overrides.

4

Add global CSS via App Settings → Custom Code → Head

For CSS that should apply project-wide — custom scrollbar styles, CSS custom properties (design tokens), root-level font-size, or overrides for WeWeb's core elements — use the head injection in App Settings. Click the gear icon in the left navigation bar to open App Settings → Custom Code. In the Head text area, add your CSS wrapped in a <style> tag. Do NOT include <html>, <head>, or <body> tags — only the <style> block itself. Global CSS declared here is injected before the closing </head> tag on every page. Use :root for CSS custom properties, body for base document styles, and specific class names for targeting WeWeb element types. Note: global CSS has no scope barrier — selectors here can match any element on any page, so use specific selectors.

typescript
1<!-- Inject point: App Settings Custom Code Head section -->
2<!-- Include only the <style> tag, not <html> or <head> tags -->
3
4<style>
5 /* CSS design tokens — reference these anywhere with var() */
6 :root {
7 --color-primary: #3b82f6;
8 --color-primary-dark: #1d4ed8;
9 --color-surface: #f8fafc;
10 --radius-card: 12px;
11 --shadow-card: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
12 --font-body: 'Inter', sans-serif;
13 --font-display: 'Sora', sans-serif;
14 }
15
16 /* Custom scrollbar */
17 ::-webkit-scrollbar { width: 6px; }
18 ::-webkit-scrollbar-track { background: transparent; }
19 ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
20 ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
21 html { scrollbar-width: thin; scrollbar-color: #cbd5e1 transparent; }
22
23 /* Smooth scroll for anchor links */
24 html { scroll-behavior: smooth; }
25
26 /* Remove default focus outline, replace with custom */
27 *:focus-visible {
28 outline: 2px solid var(--color-primary);
29 outline-offset: 2px;
30 border-radius: 2px;
31 }
32
33 /* Selection color */
34 ::selection { background: var(--color-primary); color: white; }
35</style>

Expected result: After publishing, global CSS rules apply across all pages — custom scrollbars, CSS variables, and base document styles are active.

5

Upload a custom font and use it in your project

WeWeb supports uploading custom font files directly to your project. Navigate to your project dashboard at app.weweb.io (not inside the editor — this is the project list view). Click on your project card. In the project settings, find the Fonts section. Click Upload Font. Select your font files — WeWeb accepts TTF, OTF, WOFF, and WOFF2 formats. Upload all weights and styles you need (Regular, Bold, Italic, Bold Italic). Once uploaded, return to the editor. In the Styling panel for any text element, click the Font dropdown in the Typography section. Your uploaded font now appears in the font list. Select it to apply it. Uploaded fonts are served from WeWeb's CDN and work in both editor preview and published versions.

Expected result: Your custom font appears in the Font dropdown in the Styling panel and applies correctly to text elements.

6

Add Google Fonts via Custom Code head injection

As an alternative to uploading font files, you can load Google Fonts directly via a link tag in the head injection. Navigate to fonts.google.com, select your font and desired weights (hold Shift to select multiple weights), and click 'Get embed code'. Copy the <link> tag (not the @import version). In WeWeb editor, go to App Settings → Custom Code → Head section. Paste the Google Fonts link tag. Then add a CSS custom property or apply the font via the Typography Library. To use the font in elements: Styling panel → Typography → Font dropdown — type the font name to search for it. If the font was loaded via head injection but does not appear in the dropdown, you can force it via the per-element Custom CSS field using font-family: 'Your Font Name', sans-serif;

typescript
1<!-- Inject point: App Settings Custom Code Head section -->
2<!-- Google Fonts optimized loading with display=swap and font-display -->
3<link rel="preconnect" href="https://fonts.googleapis.com">
4<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
5<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Sora:wght@400;600;700&display=swap" rel="stylesheet">
6
7<style>
8 /* Apply fonts globally via CSS variables */
9 :root {
10 --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
11 --font-heading: 'Sora', sans-serif;
12 }
13
14 /* Or apply directly to elements */
15 body { font-family: var(--font-body); }
16 h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); }
17</style>

Expected result: After publishing, Google Fonts load from Google's CDN and apply correctly to text elements across all pages.

7

Create CSS animations using the Styling panel Animations tab

WeWeb provides a visual animation editor in the Styling panel. Select an element → in the Styling panel, scroll down to find the Animations section (or click the Animations tab if your panel has tab navigation). Click Add Animation. Configure the animation properties: Duration (milliseconds), Delay (milliseconds before it starts), Timing function (ease, ease-in, ease-out, linear, or custom cubic-bezier), Iteration count (number or Infinite), Direction (normal, reverse, alternate, alternate-reverse), Fill mode (forwards keeps final state). Click Edit Keyframes to define the animation stages: click + to add a keyframe at a percentage (0% = start, 100% = end), then configure the styles at each keyframe using the Styling panel controls. WeWeb also lets you import a full keyframe definition or ask the WeWeb AI to generate animations from a text description.

typescript
1/* CSS keyframe animation — for reference / to paste into Custom CSS if needed */
2/* Per-element Custom CSS field or App Settings → Custom Code → Head */
3
4/* Fade and slide up on page load */
5@keyframes fadeSlideUp {
6 0% {
7 opacity: 0;
8 transform: translateY(24px);
9 }
10 100% {
11 opacity: 1;
12 transform: translateY(0);
13 }
14}
15
16/* Pulse effect for attention-grabbing elements */
17@keyframes pulse {
18 0%, 100% { transform: scale(1); }
19 50% { transform: scale(1.05); }
20}
21
22/* Shimmer effect for skeleton loaders */
23@keyframes shimmer {
24 0% { background-position: -200% center; }
25 100% { background-position: 200% center; }
26}
27
28/* Apply animations via class */
29.animate-fade-up {
30 animation: fadeSlideUp 0.5s ease-out both;
31}
32.animate-pulse {
33 animation: pulse 2s ease-in-out infinite;
34}
35.skeleton-loader {
36 background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);
37 background-size: 200% 100%;
38 animation: shimmer 1.5s infinite;
39}

Expected result: The element animates with the configured keyframe animation when the page loads or when the animation trigger fires.

8

Build a Typography Library for design system consistency

WeWeb's Typography Library lets you define named text styles that can be applied consistently across your project — similar to text styles in Figma or design tokens. To access it: click the Libraries icon in the left navigation bar (it looks like a book or palette icon) → Typography tab. Click + New Style. Name the style (e.g., 'Heading 1', 'Body Regular', 'Caption'). Configure the font, size, weight, line-height, letter-spacing, and color. Save. Now when you select any text element → Styling panel → Typography section → click the Typography Library icon (or look for a 'T' icon near the font name) to apply a library style. Changes to a Typography Library style automatically propagate to all elements using that style. This is the WeWeb equivalent of a design system's type scale.

Expected result: Typography Library styles appear as options in the text element Styling panel, and updating a style propagates the change to all elements using it.

Complete working example

weweb-design-system.css
1/* ============================================================
2 WeWeb Design System Global CSS
3 Inject point: App Settings Custom Code Head section
4 Wrap entire content in a <style> tag
5============================================================ */
6
7/* --- Design Tokens --- */
8:root {
9 /* Colors */
10 --color-primary: #3b82f6;
11 --color-primary-hover: #2563eb;
12 --color-primary-light: #eff6ff;
13 --color-secondary: #8b5cf6;
14 --color-success: #10b981;
15 --color-warning: #f59e0b;
16 --color-error: #ef4444;
17 --color-surface: #ffffff;
18 --color-surface-2: #f8fafc;
19 --color-border: #e2e8f0;
20 --color-text: #1e293b;
21 --color-text-muted: #64748b;
22
23 /* Typography */
24 --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
25 --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
26
27 /* Spacing scale */
28 --space-1: 4px;
29 --space-2: 8px;
30 --space-3: 12px;
31 --space-4: 16px;
32 --space-6: 24px;
33 --space-8: 32px;
34 --space-12: 48px;
35 --space-16: 64px;
36
37 /* Radii */
38 --radius-sm: 4px;
39 --radius-md: 8px;
40 --radius-lg: 12px;
41 --radius-xl: 16px;
42 --radius-full: 9999px;
43
44 /* Shadows */
45 --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
46 --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
47 --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
48
49 /* Transitions */
50 --transition-fast: 150ms ease;
51 --transition-base: 250ms ease;
52 --transition-slow: 350ms ease;
53}
54
55/* --- Base Styles --- */
56html { scroll-behavior: smooth; }
57body { font-family: var(--font-sans); color: var(--color-text); }
58
59/* --- Custom Scrollbar --- */
60::-webkit-scrollbar { width: 6px; height: 6px; }
61::-webkit-scrollbar-track { background: transparent; }
62::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
63::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }
64html { scrollbar-width: thin; scrollbar-color: var(--color-border) transparent; }
65
66/* --- Focus Styles --- */
67*:focus-visible {
68 outline: 2px solid var(--color-primary);
69 outline-offset: 2px;
70 border-radius: var(--radius-sm);
71}
72
73/* --- Selection --- */
74::selection { background: var(--color-primary); color: white; }

Common mistakes

Why it's a problem: Adding CSS to App Settings → Custom Code and wondering why it doesn't appear in the editor

How to avoid: Custom CSS from App Settings → Custom Code does NOT render in the WeWeb editor preview. You must Publish your project and view the live published URL to see the styles applied. This is by design — the editor runs in a sandboxed environment.

Why it's a problem: Including <html>, <head>, or <body> wrapper tags in the Custom Code head injection

How to avoid: Only paste the <style> tag itself (or <link> tags for fonts) — do not wrap in <html> or <head> tags. WeWeb injects your code into the existing page head, not as a complete document.

Why it's a problem: Applying the same styles directly to multiple elements instead of using a CSS class

How to avoid: Direct element styles are not reusable. Create a CSS class in the Styling panel → Classes section, add your styles to the class, then apply the same class to all elements that need those styles. When you change the class, all elements update automatically.

Why it's a problem: Writing very specific selectors in per-element Custom CSS that conflict with WeWeb's internal styles

How to avoid: WeWeb generates its own class names for elements. Use relative selectors (descendant selectors, child combinators) in per-element Custom CSS rather than trying to override WeWeb's generated class names. If you need to override WeWeb's styles specifically, use !important sparingly.

Best practices

  • Define CSS custom properties (:root variables) for colors, spacing, and typography in App Settings → Custom Code → Head so they are available everywhere in your project
  • Use the Typography Library to define your type scale — this ensures consistent font sizing across the project and makes global typography changes a one-step operation
  • Always test custom CSS on the published version, not the editor preview — editor and published rendering can differ for CSS
  • Use subclasses for hover and focus states instead of writing custom CSS — WeWeb's subclass system generates correct CSS and keeps styles in the visual editor
  • Name CSS classes and Typography Library styles semantically (describe purpose, not appearance) to make the codebase easier to maintain as it grows
  • Keep per-element Custom CSS focused on rules that cannot be expressed in the Styling panel — do not duplicate properties that the visual panel already handles
  • Test animations on mobile devices specifically — animations that look smooth on desktop can cause jank on lower-powered mobile devices, and some CSS animation properties trigger layout reflows

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am building a WeWeb app and want to add a custom design system using CSS variables for colors and spacing. Where do I inject global CSS in WeWeb, and what is the correct format? I want the CSS variables to be available across all pages in the project.

WeWeb Prompt

In my WeWeb project, I have a button that should change background color on hover. I can see the hover subclass option in the Styling panel. However, I also want the button to have a subtle scale transform on hover and a box-shadow change. Can I configure all three hover effects (background color, transform, box-shadow) using WeWeb's subclass system, or do I need to write custom CSS?

Frequently asked questions

Can I use Tailwind CSS utility classes in WeWeb?

Not natively. WeWeb does not include Tailwind CSS by default. You can inject the Tailwind CDN script via App Settings → Custom Code → Head, which makes utility classes available, but this loads the entire Tailwind stylesheet (>300KB) and is not optimized for production. For most styling needs, WeWeb's Styling panel and CSS classes system are more appropriate. If you need Tailwind specifically, self-hosting with a custom build process is the proper approach.

Do WeWeb CSS classes get exported in the code export?

Yes. When you export your WeWeb project, all CSS classes and styling are included in the compiled CSS files. The classes are exported as generated class names in the built CSS, not as your human-readable class names — but the styles themselves are fully preserved.

How do I style WeWeb components that I cannot select in the editor (like internal dropdown items)?

Use the global CSS injection in App Settings → Custom Code → Head. Inspect the published version in browser DevTools to find the generated class names of the internal elements you want to target. Write CSS rules targeting those class names in the global head injection. These styles may need !important to override WeWeb's component-level styles.

Can I use CSS Grid in WeWeb, or only Flexbox?

WeWeb's visual editor primarily exposes Flexbox controls, but CSS Grid is supported. For Grid layouts, use the per-element Custom CSS field to define grid-template-columns, grid-template-rows, and grid-area properties. You can also define grid properties in the global CSS injection and apply them via class names. WeWeb's visual Grid layout option (Columns element) provides a simplified grid implementation.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.