Admin pages in the admin4 style
Part 3, chapter 33. Most extensions add a page to the administration. It should look like the rest of it, work in dark mode and at high zoom, and cost the administration no extra CSS that drifts. The rules and the full component and token API are in Styling the administration; this chapter is the extension author's summary.
The rules
- No
<style>and nostyle=""in templates. CSS lives in your design'sstylesheets/and is loaded throughdesign.ini. - Use the shared components first:
.a4-page,.a4-card,.a4-table,.a4-btn,.a4-toolbar,.a4-filterbar,.a4-badge,.a4-notice,.a4-emptyand the others ofstylesheets/components.css. - Colors, radius, spacing and fonts only from
--a4-*tokens: they switch for dark mode by themselves. - Your own classes take your own prefix and the same rules; your stylesheet holds only what the components cannot do.
- Check light and dark, at 1440 px and at 960 px with a 200% zoom.
Your stylesheet
design/admin/stylesheets/mysite_hello.css (or design/admin4/... if the page exists only in admin4), registered as the
expqueue extension does:
[StylesheetSettings]
BackendCSSFileList[]=mysite_hello.cssExtensions add to BackendCSSFileList[], never to AdminComponentCSSFileList[] (that list is the administration's own).
expqueue's stylesheet opens with a comment worth copying: the pages "are built from the administration's shared
components ... and take every colour, radius, size and space from the --a4-* tokens of components.css, which have a
light and a dark value. This file holds only what the components cannot do, as .a4-queue-* classes."
/* mysite_hello: the Hello admin page. Built from the shared components; only what they cannot do is here. */
.a4-hello-list {
display: grid;
gap: var(--a4-space-3);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.a4-hello-name {
color: var(--a4-accent-text);
font-size: var(--a4-text-l);
}A page template
design/admin4/templates/hello/admin.tpl:
<div class="a4-page">
<div class="a4-pagehead">
<div class="a4-pagehead-main">
<h1 class="a4-pagehead-title">{'Greetings'|i18n( 'extension/mysite_hello' )}</h1>
</div>
</div>
{if $greetings|count}
<div class="a4-table-wrap">
<table class="a4-table">
<thead><tr><th scope="col">{'Name'|i18n( 'extension/mysite_hello' )}</th><th scope="col">{'When'|i18n( 'extension/mysite_hello' )}</th></tr></thead>
<tbody>
{foreach $greetings as $greeting}
<tr><td>{$greeting.name|wash}</td><td>{$greeting.created|l10n( 'shortdatetime' )}</td></tr>
{/foreach}
</tbody>
</table>
</div>
{else}
<p class="a4-empty">{'No greetings yet.'|i18n( 'extension/mysite_hello' )}</p>
{/if}
<form method="post" action={'/hello/admin'|ezurl} class="a4-toolbar">
<button type="submit" name="ClearButton" class="a4-btn a4-btn-danger">{'Clear all'|i18n( 'extension/mysite_hello' )}</button>
</form>
</div>An empty list says so in .a4-empty, data tables use .a4-table (striped by the administration), forms post with the
form token added automatically.
Classic admin and other designs
The classic admin design has an identical copy of components.css, so the same classes work there; put the template
in design/admin/templates/ too when your page must work in both. Designs without the component classes still get
readable HTML.
The left menu
Add a link to an administration menu in your extension's settings/menu.ini.append.php. expqueue adds its
"Job queue" to the Setup menu like this, with the policy a user needs to see the link:
[Leftmenu_setup]
Links[expqueue]=expqueue/dashboard
LinkNames[expqueue]=Job queue
PolicyList_expqueue[]=expqueue/viewA menu that is divided into groups places a link with GroupLinks_<group>[]; a link in no group shows under "More".
Accessibility
- One
h1(the page title), thenh2/h3in order. - Every form field has a label; every icon-only button has text for screen readers (
.a4-sr-only) and atitle. - Notices that report a result have
role="status"(orrole="alert"for errors). - Text contrast at least 4.5:1, which the tokens give you if you use them.
Check
Open the page in light and dark mode, at 1440 px and at 960 px with the browser at 200%: no white card on the dark page, no horizontal scroll bar, no console errors (including Content Security Policy reports).
Related pages
- Previous: Content Security Policy for extension authors
- Next: Tests for extensions
- Styling the administration
- admin4 components and tokens
- admin4 styling for extension pages
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.