Skip to main content

Style Guide

How Styles are applied

All application-wide styles — colors, component defaults, and theme variables — are configured through Vuetify's plugin interface. The createVuetify() call receives a theme definition and component defaults that apply globally:

export const createVuetifyPlugin = (i18n: ReturnType<typeof createI18n>) =>
createVuetify({
...(useEnvConfig().value.SC_THEME === SchulcloudTheme.DEFAULT
? dbcThemeOptions
: federalStateThemeOptions),
defaults: {
VTextField: { variant: "underlined", color: "primary" },
// ...
},
});

The theme itself is built on a base theme (base-vuetify-theme.options.ts) that defines colors, surface tokens, and CSS variables for the entire application:

const baseTheme: ThemeDefinition = {
dark: false,
colors: {
primary: "#9e292b",
// ...
}
};

Instance-specific themes (e.g. for federal states) extend or override values from this base. Vuetify then generates CSS variables (e.g. --v-theme-primary) from these definitions, making them available everywhere via rgba(var(--v-theme-primary)).

Colors

Colors are included as CSS properties, often with transparency:

color: rgba(var(--v-theme-primary));
background-color: rgba(var(--v-theme-on-surface), 0.6);

Theme

Federal State Instances

src/themes/vuetify-theme.options.ts

ColorTokenHexUsage
primary#2370CBButton, Toolbar, Switch, Checkbox, Select, Progress Bar
primary-darken-1#1e599cDataTable Header, Sort Icon
primary-lighten#e9f1faCard Header (e.g. News)
on-surface-light / on-surface /
on-background / on-white
#0f3551Text, Icons, Chip Text, Alert Text
surface-light#f2f5f9Boards (in Rooms), Filters (in Tasks)

dBildungscloud

src/themes/base-vuetify-theme.options.ts

ColorTokenHexUsage
primary#9e292bButton, Toolbar, Switch, Checkbox, Select, Progress Bar
primary-darken-1#800416DataTable Header, Sort Icon
primary-lighten#f5eaeaCard Header (e.g. News)
on-surface-light / on-surface /
on-background / on-white
#3a424bText, Icons, Chip Text, Alert Text
surface-light#f3f4f4Boards (in Rooms), Filters (in Tasks)

Background

src/themes/base-vuetify-theme.options.ts

ColorTokenHexUsage
surface-variant#4E555DAvatar, Tooltip (Background)
on-surface-variant#F7F7F8Text/Icons on surface-variant
white#ffffffToolbar, Board

Info, Warning, Error

src/themes/base-vuetify-theme.options.ts

ColorTokenHexUsage
info#0a7ac9Alert, Chip
success#13ba98Alert, Status Icon
warning#ff8311Alert, Chip, Status Icon (Tool deactivated/outdated)
error#ed0122Alert, Chip, Status Icon, Error Text

Rooms

Room Colors

src/styles/utility/_room-colors.scss

ColorCSS ClassHex
.room-color--blue-grey#455b6a
.room-color--pink#ec407a
.room-color--red#d50000
.room-color--orange#ef6c00
.room-color--olive#827717
.room-color--green#689f38
.room-color--turquoise#009688
.room-color--light-blue#0091ea
.room-color--blue#304ffe
.room-color--magenta#d500f9
.room-color--purple#9c27b0
.room-color--brown#795548
.room-color--yellow#ffc107

Boards

Card Background Colors (lighten5)

src/utils/color.utils.ts

Note: Hex values are computed at runtime via colors[color]["lighten5"] from Vuetify's color palette and are shown here for reference only. Use the Colors enum in code.

ColorColors EnumHex
transparent#ffffff
lightGreen#f1f8e9
green#e8f5e9
cyan#e0f7fa
blue#e3f2fd
indigo#e8eaf6
purple#f3e5f5
pink#fce4ec
deepOrange#fbe9e7
amber#fff8e1
blueGrey#eceff1

Font Color in CK5 Editor

src/modules/feature/editor/config.ts

ColorLabelHex
Olive Green#827717
Green#388E3C
Turquoise#00838F
Blue#1976D2
Indigo#3F51B5
Dark Purple#673AB7
Purple#9C27B0
Pink#D81B60
Red#D32F2F

Text Highlighting in CK5 Editor

src/modules/feature/editor/config.ts

ColorLabelHex
Light Green#DCEDC8
Green#C8E6C9
Turquoise#B2EBF2
Blue#BBDEFB
Indigo#C5CAE9
Dark Purple#E1BEE7
Pink#F8BBD0
Orange#FFCCBC
Yellow#FFECB3

Typography

Typography is defined via CSS variables and Vuetify utility classes, applied directly in templates and stylesheets:

<!-- Room abbreviation in avatar (RoomGridItem.vue) e.g. for Math 5a -->
<span class="text-h1 text-white">Ma</span>

<!-- Board file element: Metadata (FileAttributes.vue) -->
<span class="text-caption">3 Files · 1.2 MB</span>
.board-title {
font-family: var(--font-accent);
font-size: var(--heading-1);
}

Fonts

src/styles/css-variables/_typography.scss

VariableFont FamilyUsage
--font-primaryPT Sans, System FallbackBody text, UI elements
--font-accentPT Sans Narrow, System FallbackHeadings (h1h6)

Typographic Scale

Headings

src/styles/utility/_typography.scss

ElementCSS VariableSizeWeightLine-Height
h1--heading-12.0625rem (33 px)normal--line-height-body (1.3)
h2--heading-21.625rem (26 px)normal--line-height-body (1.3)
h3--heading-31.375rem (22 px)bold--line-height-body (1.3)
h4--heading-41.25rem (20 px)bold--line-height-lg (1.4)
h5--heading-51.125rem (18 px)bold--line-height-lg (1.4)
h6--heading-61rem (16 px)bold--line-height-lg (1.4)

Vuetify Typography

Vuetify provides its own text classes that can be used independently of the HTML element:

ClassSizeUsage
.text-h1.text-h6--heading-1--heading-6 (see Headings table)Heading style without semantic h element
.text-subtitle-11 remSection labels, form labels
.text-subtitle-20.875 remSecondary labels, due dates
.text-body-11 remDefault body text, card titles
.text-body-20.875 remSecondary text, hint text
.text-caption0.75 remMetadata, file attributes

Font Size Classes

src/styles/utility/_typography.scss

ClassCSS VariableSize
.text-xs--text-xs0.694rem (≈ 11 px)
.text-sm--text-sm0.833rem (≈ 13 px)
.text-md--text-md1rem (16 px)
.text-lg--text-lg1.2rem (≈ 19 px)

Line-Heights

VariableValueUsage
--line-height-md1.2Board title
--line-height-body1.3h1h3, Body text
--line-height-lg1.4h4h6
--line-height-xl1.5Text in boards

Spacing

Vuetify Spacing Scale

Vuetify uses 4px as the base unit with utility classes following the pattern {property}{direction}-{n}:

<VCard class="pa-4"></VCard> <!-- padding: 16px; -->
<VCard class="mt-6 mb-2"></VCard> <!-- margin-top: 24px; margin-bottom: 8px; -->
<VCard class="mx-auto"></VCard> <!-- margin-left: auto; margin-right: auto; -->
  • Property: m (margin), p (padding)
  • Direction: t top, b bottom, l left, r right, x horizontal, y vertical, none = all sides
px481216202432404864
n1234568101216

Layout Sizes

Layout sizes are defined as CSS variables for consistent structural dimensions across the application:

src/styles/css-variables/_layout-sizes.scss

VariableValueUsage
--topbar-height50pxHeight of the top navigation bar
--breadcrumbs-height22pxHeight of the breadcrumb row
--footer-height50pxHeight of the footer
--content-min-width30chMinimum content width
--content-max-width80chMaximum content width (text)
--content-limited-width1200pxMaximum page width

Icons

Material Design Icons

src/components/icons/material/index.ts

The outline variant is preferred (e.g. mdiAccountOutline instead of mdiAccount). Icons are imported and passed as a prop to components or as a property in configuration objects:

import { mdiNewspaperVariantOutline, mdiFolderOpenOutline } from "@icons/material";
<!-- directly to VIcon (Dashboard.page.vue) -->
<VIcon size="14" class="mr-1" :icon="mdiNewspaperVariantOutline" />

<!-- as a prop to a custom component (FolderContentElement.vue) -->
<ContentElementBar :icon="mdiFolderOpenOutline">
// RoomBoardCard.vue – icon as a property in menu actions (RoomDotMenu)
actions.push({
icon: mdiTrashCanOutline,
action: () => emit("delete-board"),
name: t("common.actions.delete"),
});

Icons are used in:

  • UI elements: menu, sidebar, tabs, icon buttons
  • Content types: tasks, folders, boards, board-elements

A full searchable overview of all available icons is at pictogrammers.com/library/mdi.

Custom Icons

src/components/icons/custom/

Custom SVG icons as Vue components, registered as Vuetify aliases in base-vuetify-theme.options.ts:

<VIcon icon="$h5pOutline" />
AliasDatei
$gridRowOutlinegrid-row-outline.vue
$h5pOutlineh5p-outline.vue
$langIconDelang-icon-de.vue