Cassiopeia and Cassiopeia Extended

This content was generated with the assistance of AI and should be verified against the official Joomla documentation before being relied on in production.

This sub-section’s Joomla bibliography lists the reference material consulted while preparing these pages.

Cassiopeia is the default front-end (site) template of Joomla 4 and later. Every fresh installation starts with it, and for many sites it is the only template that is ever used: it is responsive, built on Bootstrap 5 and CSS Grid, and it is configured through a handful of options on its template style instead of by editing files. Joomla 6.0 added a second, sibling template to the core, cassiopeia_extended, a child of Cassiopeia that replaces the fixed "standard" and "alternative" colour themes with twelve colour pickers and adds font-size settings. This page explains both: what each option does, how the options become CSS and markup, which module positions the layout offers, which CSS custom properties a themer can rely on, what Bootstrap 5.3 contributes, and where colour modes (dark mode) stand. It was checked against the official documentation and the 6.2 source tree on 2026-10-30, and describes Joomla 6.2 (current, requiring PHP 8.3 or newer). Joomla 5.4 (security fixes only) has Cassiopeia but not cassiopeia_extended; Joomla 4.x and 3.x are end of life.

The examples belong to the Tallpine Hiking Club, the fictitious mountain club used across this sub-section. Its site runs the child template cassiopeia_tallpine (see Child templates), which adds positions, a forest-green colour scheme and a slightly larger body font. The general idea of template styles and how a template is chosen per menu item is in Templates and template styles; building a template without a parent is in Building a template from scratch.

Who works with Cassiopeia, and where

  • Editors and site builders open System → Site Template Styles, select Cassiopeia - Default and use the Advanced tab. They also place modules in positions (see Modules and positions).

  • Themers add a user.css through System → Site Templates → Cassiopeia Details and Files, create template overrides and, for anything larger, a child template.

  • Developers read templates/cassiopeia/index.php and templateDetails.xml to see which parameter drives which markup or style, and register assets with the Web Asset Manager (see Web Asset Manager).

The template has two parts on disk. The PHP and XML (index.php, component.php, error.php, offline.php, templateDetails.xml, joomla.asset.json and the html override folder) live in templates/cassiopeia/. The CSS, JavaScript, SCSS and images are installed under media/templates/site/cassiopeia/ and are built from media_source/ in the source tree. A template style is a row holding the parameter values for one template; one template can have many styles, and each menu item can pick a style. Parameters of Cassiopeia and of cassiopeia_extended are stored per style, so the values below are not global.

Cassiopeia’s style options

Open System → Site Template Styles, click Cassiopeia - Default and choose the Advanced tab. The fields come from the advanced fieldset of templateDetails.xml.

Option (parameter) Values and default Effect

Brand (brand)

Yes (default) or No

Shows the brand bar of the header. With No, the logo, title and tag line fields are hidden (they use showon="brand:1") and the brand block is not rendered at all.

Logo (logoFile)

Media picker, empty by default

When set, the image is output in the brand link and wins over the title. When empty and no title is set, Cassiopeia’s own logo.svg is used.

Title (siteTitle)

Text, empty

Shown in the brand link when no logo image is chosen. The value is escaped with htmlspecialchars().

Tag line (siteDescription)

Text, empty

A small line under the brand, rendered in div.site-description.

Fonts Scheme (useFontScheme)

None (default), System, Roboto (local), Fira Sans (web), Roboto + Noto Sans (web)

See Font schemes.

System font for body / headings (systemFontBody, systemFontHeading)

One of thirteen font stacks, shown only when the scheme is System

Sets --cassiopeia-font-family-body and --cassiopeia-font-family-headings.

Color Theme (colorName)

Standard (default, dark blue) or Alternative (maroon)

Loads colors_standard.css or colors_alternative.css. The list also offers any file named custom*.css in media/templates/site/cassiopeia/css/global/.

Layout (fluidContainer)

Static (default) or Fluid

Adds wrapper-static or wrapper-fluid to <body>. Static caps the width at 1320 px; fluid has no maximum.

Sticky Header (stickyHeader)

No (default) or Yes

Adds the Bootstrap classes position-sticky sticky-top to the <header> so it stays at the top of the viewport. The User Guide describes the effect for wider screens.

Back-to-top Link (backTop)

No (default) or Yes

Outputs a#back-top.back-to-top-link with an arrow icon and an aria-label from the language string TPL_CASSIOPEIA_BACKTOTOP, pinned at the bottom right.

The User Guide lists sixteen positions and the four layout and header switches above; it does not mention the font stacks of the System scheme or the custom colour files, which are in the manifest. Older material (Marzo’s Joomla! 4 Masterclass, 2023, and tutorials of that era) shows the same Advanced tab, but its description of Cassiopeia as the new template of Joomla 4 and of child templates as a novelty is out of date: child templates have been standard since 4.1 and Joomla 6.0 ships one in the core.

Brand, title and tag line in practice

For the Tallpine site the board wants the club logo in the header and a short line under it. In Advanced set Logo to images/tallpine/logo.svg, leave Title empty and enter Tag line Hiking since 1962. Because the logo wins over the title, a leftover title is not shown, but it is still the text used as the image alternative: Cassiopeia passes the site name (from Global Configuration) as the alt text of the logo, so a descriptive site name matters for accessibility (see Accessibility). Turning Brand off removes the whole bar, which is useful only when a topbar or menu module carries the identity.

Layout, sticky header and back-to-top

Layout only toggles a body class. The width limit itself comes from the template CSS, so a child template that wants a narrower page changes it in user.css (for example by setting max-width on .container-header and .site-grid). A sticky header takes vertical space from the page: on small screens or with large zoom, a tall header can cover the heading that a keyboard user has just focused, so test focus visibility with the header enabled. The back-to-top link is a plain anchor to #top, which is the id of <body>, so it works without JavaScript.

Font schemes

The Fonts Scheme list is handled in templates/cassiopeia/index.php and has four behaviours:

  1. None adds nothing; the font family comes from the template stylesheet and Bootstrap’s system stack.

  2. System reads the two stack lists (systemFontBody and systemFontHeading) and writes --cassiopeia-font-family-body, --cassiopeia-font-family-headings and the matching font weights into an inline :root block. Nothing is downloaded. The thirteen stacks are named, among others, Transitional, Old Style, Humanist, Geometric, Classical, Grotesque, Monospace, Code, Industrial, Rounded, Slab, Antique, Didone and Handwritten.

  3. Roboto (local) registers global/fonts-local_roboto.css as a lazy stylesheet. The font files ship with the template, so no third party is contacted.

  4. Fira Sans (web) and Roboto + Noto Sans (web) load a Google Fonts stylesheet. Cassiopeia emits preconnect and preload hints for fonts.googleapis.com and fonts.gstatic.com, derives the family names from the URL and sets the same custom properties.

The web options send every visitor’s IP address to a third party, which many data-protection rules treat as personal data that needs a legal basis or consent. A Tallpine site for German members should therefore prefer the local Roboto or a system stack (see Privacy and action logs for the privacy tooling). The web schemes also depend on the visitor’s network: when Google Fonts is blocked the text falls back to the sans-serif declared with the font.

Module positions

Cassiopeia declares eighteen positions in templateDetails.xml: topbar, below-top, menu, search, banner, top-a, top-b, main-top, main-bottom, breadcrumbs, sidebar-left, sidebar-right, bottom-a, bottom-b, footer, debug, error-403 and error-404. The two error positions are drawn directly by error.php. The User Guide counts sixteen because it leaves those two out. cassiopeia_extended declares the same eighteen, so existing module assignments keep working when a site switches styles.

The structure that index.php produces is a header (topbar, below-top, brand, menu with search), a CSS Grid called site-grid (banner, top-a, top-b, left sidebar, the component column with breadcrumbs, main-top and main-bottom, right sidebar, bottom-a, bottom-b), a footer and the debug position. Every block is wrapped in countModules() so an empty position leaves no empty column; the layout then gains the body classes has-sidebar-left and has-sidebar-right that the grid uses to size the component column. Moving a module is a matter of changing its Position on the module, and Preview Module Positions (?tp=1) shows all of them. The full description, with a diagram, the default module style per position and the child template that adds trail-conditions and partner-strip, is in Modules and positions; the markup of module styles is in Layouts and module chromes.

One detail catches new users: the menu position outputs the module with the Cassiopeia menu layouts (Collapsible Dropdown or Dropdown) only when the module’s Layout on the Advanced tab is switched from the module’s own layout to the one "From Cassiopeia Template"; the default layout does not display child items. A menu moved to topbar sits further to the left than in menu, because topbar has no grid-child class.

Cassiopeia Extended (Joomla 6.0)

cassiopeia_extended was added in 6.0 (released 2025-10-14) as a working example of a core child template. The release news describes it as a child template offering extended colour and font options, so that a site can define more colours and font sizes without writing a custom CSS file. After a fresh installation or an update to 6.0 it appears in System → Site Template Styles as an extra style; clicking the star in the Default column makes it the site template. The 6.0 work was merged in two steps (a first child template, then a revision with its parameters and a style created by the installer), and 6.0.x fixed the validation of the font-size fields.

Its manifest is short and has these properties:

  • <parent>cassiopeia</parent>, so it inherits every file it does not ship.

  • <inheritable>0</inheritable>, so it cannot itself be the parent of another template. Cassiopeia has <inheritable>1</inheritable>. This is why cassiopeia_tallpine extends cassiopeia, not cassiopeia_extended.

  • it ships only component.php, error.php, index.php, offline.php, an html folder and the media folders css, images and scss. Its index.php is 43 lines and starts with require JPATH_THEMES . '/cassiopeia/index.php'.

  • the same eighteen positions as Cassiopeia.

  • the advanced fieldset of Cassiopeia (brand, logo, title, tag line, fluid layout, sticky header and back-to-top) plus two new fieldsets, Colors and Fonts. The Color Theme choice of the parent is gone, and so is the web-font list: its font list has the same entries (None, System, local Roboto, the two Google Fonts schemes).

The twelve colour parameters

The Colors tab has twelve colour fields, all with format="rgb". The template style stores them as rgb(r, g, b) text.

Parameter Default CSS custom property it sets Used for

headerbg

rgb(193, 205, 207)

--headerbg

Header background (the parent’s gradient is replaced by a flat colour).

headercolor

rgb(23, 23, 23)

--headercolor

Brand link and main menu text in the header.

bodybg

rgb(254, 254, 254)

--body-bg

Page background.

bodycolor

rgb(23, 23, 23)

--body-color

Body text, and the checked state of form check boxes.

linkcolor

rgb(29, 121, 137)

--link-color

Links, the active pagination page, the card accent of blog items.

linkcolorh

rgb(14, 59, 67)

--link-hover-color

Link hover.

btnbg, btnbgh

rgb(206, 60, 55), rgb(131, 35, 32)

--btnbg, --btnbgh

Primary button background and its hover, focus and active background.

btncolor, btncolorh

both rgb(254, 254, 254)

--btncolor, --btncolorh

Primary button text and its hover text.

footerbg, footercolor

rgb(29, 121, 137), rgb(254, 254, 254)

--footerbg, --footercolor

Footer background, and footer text and links.

The four font-size parameters

The Fonts tab repeats the parent’s font scheme and the two system-stack lists, shows a warning note, and adds four numeric fields expressed in rem: bodysize (default 1), h1size (2), h2size (1.7) and h3size (1.5). They become --body-font-size, --h1size, --h2size and --h3size. The stylesheet global/fonts.css applies the three heading sizes only from a viewport width of 1200 px (@media (width >= 1200px)), so on phones and tablets headings keep the parent’s smaller, fluid sizes. The fields are validated as numbers with a minimum of 0; a value of 0 therefore passes validation and makes the text invisible, so keep values positive.

How the parameters reach the page

cassiopeia_extended/index.php does not copy the parent’s template. It requires the parent file, then uses the Web Asset Manager to add two stylesheets and two inline :root blocks:

<?php
defined('_JEXEC') or die;

/** @var Joomla\CMS\Document\HtmlDocument $this */

require JPATH_THEMES . '/cassiopeia/index.php';

$wa = $this->getWebAssetManager();

$wa->registerAndUseStyle('colors_custom', 'global/colors.css')
    ->addInlineStyle(':root {
        --body-bg: ' . $this->params->get('bodybg') . ';
        --link-color: ' . $this->params->get('linkcolor') . ';
        /* ... ten more colour properties ... */
    }')
    ->registerAndUseStyle('font_advanced', 'global/fonts.css')
    ->addInlineStyle(':root {
        --body-font-size: ' . $this->params->get('bodysize') . 'rem;
        --h1size: ' . $this->params->get('h1size') . 'rem;
    }');

Source: Joomla Manual: Web Asset Manager (the excerpt is shortened from the 6.2 source of templates/cassiopeia_extended/index.php)

The flow therefore has three layers, which is also the order in which they apply:

flowchart LR P[Template style parameters: headerbg, linkcolor, h1size] --> I[index.php of cassiopeia_extended] I --> R[require cassiopeia/index.php: theme CSS, font scheme, markup] I --> C[Inline root block with the custom properties] C --> S[global/colors.css and fonts.css read the properties with var] R --> B[Rendered page] S --> B

Two consequences follow. First, the colour values are written into a <style> block unescaped, so the field type and its rgb format are what keep markup out of them; anything that writes the parameters from outside the Administrator (a script, a database edit, an import) must apply the same validation. Second, because the parent’s index.php still runs with its own colorName default (colors_standard), the parent’s standard theme properties, such as --cassiopeia-color-primary that the card headers use, are still defined and are not changed by the twelve pickers. A site that needs those too overrides them in a user.css.

Using the extended style for Tallpine

Because cassiopeia_extended cannot be a parent, there are two ways to use it for the club site. The first is to duplicate its style (Duplicate in the Site Template Styles toolbar), set the twelve colours and the four sizes in the style, and keep cassiopeia_extended as the site template. The second is to keep cassiopeia_tallpine as the child of cassiopeia and copy the values into its own style or into user.css. The Tallpine board prefers the second, because the child also owns the trail-conditions position, overrides and its joomla.asset.json, and a duplicated style cannot own them.

CSS custom properties

Cassiopeia exposes its design through custom properties on :root. The ones a themer meets most often are below. They come from colors_standard.css, colors_alternative.css, the inline block of index.php and, in the extended template, the extra inline block.

Property Meaning

--link-color, --link-hover-color

The current link and hover colours. The -rgb variants (--link-color-rgb, --link-hover-color-rgb) hold the same colours as comma-separated channels for Bootstrap’s rgba(var(--...)) pattern. The standard theme sets them from hsl(220, 67%, 40%) and hsl(242, 30%, 36%), the alternative theme from hsl(207, 49%, 37%) and hsl(351, 33%, 44%).

--cassiopeia-color-primary

The theme’s main colour (dark blue, or maroon in the alternative theme). Header gradient and card headers derive from it.

--cassiopeia-color-hover

The theme’s hover colour, used with the primary colour in the header gradient.

--cassiopeia-color-link

Deprecated alias of --link-color. See below.

--cassiopeia-font-family-body, --cassiopeia-font-family-headings, --cassiopeia-font-weight-normal, --cassiopeia-font-weight-headings

Set by the font scheme (see Font schemes).

--hue, --template-bg-light, --template-text-dark, --template-text-light, --template-link-color, --template-special-color

Set in the inline block of index.php. --template-link-color is var(--link-color).

--headerbg, --headercolor, --body-bg, --body-color, --btnbg, --btnbgh, --btncolor, --btncolorh, --footerbg, --footercolor, --body-font-size, --h1size, --h2size, --h3size

Only in cassiopeia_extended; see the tables above.

Older Cassiopeia code and third-party templates read the link colour from a Cassiopeia-specific property. In the 6.2 source the SCSS of both colour themes carries a comment saying that --cassiopeia-color-link is deprecated in favour of --link-color, and sets both to the same value. The comment gives no removal version (and misspells the name of the property as casiopeia). Joomla’s backward-compatibility policy removes deprecated code in the second major release after the deprecation, and the SCSS names 7.0 only for enabling dark mode; because no removal date is published, read --link-color in every stylesheet that has to survive the next major upgrade, and treat the Cassiopeia-prefixed property as something that may disappear without further notice. A search of a child template and its extensions for the old name is a cheap item in the 7.0 preparation checklist (see Deprecations and preparing for Joomla 7). Some tutorials and notes refer to the property as --cassiopeia-link-color; there is no property with that name in the 6.2 stylesheets, so a rule using it does nothing.

Customising without editing core files

Never edit files in templates/cassiopeia/ or media/templates/site/cassiopeia/: the next Joomla update replaces them. There are three safe layers, in increasing order of effort.

  1. Style options: everything on the Advanced tab (and the Colors and Fonts tabs of the extended style).

  2. user.css and user.js: Cassiopeia registers the assets template.user for css/user.css and js/user.js in its joomla.asset.json. If the files exist under media/templates/site/<template>/, they are loaded after the template CSS. The Template Manager creates them from Cassiopeia Details and Files, in the css and js folders. Because they live in the media folder of the template, updates do not touch them.

  3. A child template: anything involving PHP, overrides, new positions or new assets (see Child templates and Template overrides and alternative layouts).

The Tallpine user.css

/* media/templates/site/cassiopeia_tallpine/css/user.css */
:root {
  --link-color: rgb(21, 101, 72);
  --link-hover-color: rgb(10, 54, 38);
  --cassiopeia-color-primary: rgb(26, 74, 53);
  --cassiopeia-color-hover: rgb(36, 94, 64);
}

.container-header {
  background-image: none;
  background-color: var(--cassiopeia-color-primary);
}

.container-footer {
  background-color: var(--cassiopeia-color-primary);
  background-image: none;
}

.container-trail-conditions {
  border-left: 0.5rem solid var(--link-color);
  padding-inline: 1rem;
}

Defining the properties in user.css works because it loads after the template stylesheet and its :root block has the same specificity; the later rule wins. Setting --cassiopeia-color-link instead would still change links in 6.2 but not in later versions, which is why --link-color is used. Check the final colour pairs for contrast (the WebAIM contrast checker is recommended by the User Guide) before publishing, in particular link text on the page background and the footer text on the footer colour.

A child template that follows the extended pattern

A child template can do what cassiopeia_extended does with its own parameters. The Tallpine index.php requires the parent file, then registers its own asset and sets the properties from a style parameter:

<?php
// templates/cassiopeia_tallpine/index.php
defined('_JEXEC') or die;

/** @var Joomla\CMS\Document\HtmlDocument $this */

require JPATH_THEMES . '/cassiopeia/index.php';

$wa     = $this->getWebAssetManager();
$accent = $this->params->get('accent', 'rgb(21, 101, 72)');

$wa->useStyle('template.tallpine')
    ->addInlineStyle(':root { --tallpine-accent: ' . htmlspecialchars($accent, ENT_QUOTES, 'UTF-8') . '; }');
{
  "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
  "name": "cassiopeia_tallpine",
  "version": "1.0.0",
  "assets": [
    {
      "name": "template.tallpine",
      "type": "style",
      "uri": "tallpine.css"
    }
  ]
}

The htmlspecialchars() call is a deliberate difference from the core template: a parameter that can be edited by any administrator and is printed inside a <style> element is a cross-site scripting path if it is ever filled by something other than a colour picker. The parameter itself belongs in the child’s templateDetails.xml as a field of type color with format="rgb".

Bootstrap 5.3 in Cassiopeia

Cassiopeia compiles Bootstrap 5 from the copy in media/vendor/bootstrap (the 6.2 tree depends on bootstrap ^5.3.8) into its own template.css. Its template.scss imports Bootstrap’s functions, variables, maps, mixins and utilities, then the whole Bootstrap SCSS, then the template’s blocks and overrides for buttons, forms, modals, navigation, pagination and tables. Three practical consequences follow.

  • Utilities are available in overrides and layouts. Classes such as d-flex, justify-content-between, gap-3, mb-4, text-bg-secondary, visually-hidden and position-sticky work in a module, an article layout or a template override without any extra CSS. Cassiopeia itself uses position-sticky sticky-top for the sticky header. The Bootstrap JavaScript for modals, collapse, tabs and tooltips is loaded by the Web Asset Manager on demand, not with the template.

  • Bootstrap variables are not redefined at runtime. Bootstrap SCSS variables ($primary, $enable-dark-mode) are fixed at compile time. A child template can only change the custom properties Bootstrap exposes at runtime (for example --bs-link-color), or ship its own compiled CSS.

  • The grid is CSS Grid, not Bootstrap’s. The page layout comes from the template’s site-grid; the Bootstrap grid (row, col-md-6) is available inside the content area for article and module layouts.

The Atum administrator template shares the same Bootstrap copy; see The Administrator template Atum. Page builders and third-party frameworks that replace Cassiopeia’s CSS are covered in Template frameworks and page builders.

Colour modes (dark mode)

Joomla defines an API for colour schemes: a template that offers light, dark or follow-the-operating-system sets the attribute data-color-scheme on <html> to light or dark, sets data-color-scheme-os when it follows the system setting through CSS media queries, and fires the joomla:color-scheme-change event so that extensions such as editor plugins can load a matching theme. Atum implements it with a switch (added in 5.1). Cassiopeia does not: the shared SCSS variables compile with $enable-dark-mode: false, and the comment next to it says that dark mode was kept out of the 4.x series to avoid backward-compatibility breaks and is planned to be enabled in 7.0. A Tallpine member who has set the operating system to dark therefore sees the light site in Joomla 6.2.

A site that needs a dark theme today has three options: provide a dark colour scheme file (a custom*.css that sets --link-color, --cassiopeia-color-primary and the --body-* properties inside a @media (prefers-color-scheme: dark) block), duplicate the extended style with dark colours and switch it per menu item or language, or accept the light page. Whatever is chosen, set color-scheme and the data-color-scheme attribute consistently so that form controls and the TinyMCE editor in frontend editing follow. Accessibility checks, right-to-left languages and the interaction of colour schemes with contrast are in Colour modes, RTL and accessibility.

Common errors and pitfalls

  • Editing the wrong style. The menu items of a multilingual site often have different template styles. Changing the default style has no effect on an item that is pinned to another.

  • Colour pickers write rgb(...), but CSS written by hand uses hex. Mixing formats is fine, but the -rgb channel variants (--link-color-rgb) are not updated by the extended pickers, so Bootstrap rules that use rgba(var(--link-color-rgb), .5) keep the parent’s colour.

  • A big title and a logo. The logo hides the title; if you want text with an icon, use the title and a background image.

  • Positions that exist only in the child. A module assigned to trail-conditions disappears when the site returns to cassiopeia_extended, because that template does not output the position.

  • Overriding with !important. Rules for the --cassiopeia-* properties and --link-color are on :root, so a rule on a descendant such as .card { --link-color: ... } limits the change to that element; !important is almost never needed.

  • Large heading sizes. The h1size, h2size and h3size values apply only above 1200 px; check the heading at 360 px width.

  • Web fonts and caching. The web font schemes depend on fonts.googleapis.com; if the site is behind a strict Content Security Policy, those hosts must be allowed (see Security hardening, MFA and passkeys).

Version notes

  • Cassiopeia replaced Protostar as the default site template in Joomla 4.0. The Advanced tab, with the Color Theme choice, Layout, Sticky Header and Back-to-top Link, is the same in 4.x, 5.x and 6.x.

  • Child templates (4.1) are the standard way to customise Cassiopeia; since 4.1 the Template Manager can create a child from the parent’s style.

  • Joomla 6.0 (2025-10-14) adds cassiopeia_extended with the Colors and Fonts tabs. It is also in 6.1 and 6.2.

  • In 6.1, child templates extend the language file of the parent instead of replacing it, so a child no longer has to copy every string of the parent.

  • The Cassiopeia-prefixed link property is deprecated in 6.2, and the template’s SCSS notes that dark mode is to be enabled in 7.0. Neither a removal nor the dark mode is shipped behaviour in 6.x.

See Where older books and tutorials are outdated for the other points where books of the Joomla 4 and 5 era differ from the current documentation.