Skip to content
Alan Paynter edited this page Jul 19, 2026 · 1 revision

Styling Guide

How eveBB's style system works, how the bundled Carbon style is put together, and how to build and ship your own style.

What a style is

A style in eveBB is, at minimum, one CSS file:

style/<Name>.css          required — the whole style
style/<Name>/             optional — the style's asset folder
style/<Name>/img/         theme images
style/<Name>/base_admin.css   optional admin-console CSS
style/<Name>/style.json   optional manifest (for the admin Styles page)
style/<Name>/*.tpl        optional per-style template overrides

There is no build step, no preprocessor, no @import chain — a style is plain CSS. Discovery is filesystem-driven: any *.css file directly in style/ appears automatically in the style dropdowns (in profiles, the installer, and Administration → Options). Underscores in the file name are displayed as spaces in the UI.

eveBB ships one style, Carbon:

style/
├── Carbon.css            the complete stylesheet (~36 KB)
├── Carbon/
│   ├── base_admin.css    Carbon's admin-console CSS
│   └── img/              asterisk.png, bull.png, email.png, exclaim.png,
│                         ext.png, feed.png, help.png
└── imports/
    └── base_admin.css    fallback admin CSS for styles that don't ship one

Style-independent images (the default logo, default avatar, smilies, the new-post icon img/icon-newpost.svg) live in the board-root img/ directory, not in the style.

How styles are selected and loaded

  • Each user picks a style in Profile → Display (the dropdown appears only when more than one style is installed); guests get the board default (o_default_style, set in Administration → Options; Carbon after a fresh install).

  • header.php emits the stylesheet link on every page:

    <link rel="stylesheet" type="text/css" href="style/<style>.css" />

    Note there is no cache-busting parameter on this link — after editing a stylesheet, tell users to hard-refresh (or temporarily rename the style) if they see stale CSS.

  • On admin pages only (PUN_ADMIN_CONSOLE), a second stylesheet is added: style/<style>/base_admin.css if the style ships one, otherwise the fallback style/imports/base_admin.css. If you don't provide admin CSS, the admin console still works — it just uses the plain fallback look.

Inside Carbon.css

Carbon.css is a single, sectioned file. Reading it top to bottom:

  1. Initial settings — a limited reset and content defaults.
  2. Common styles — page layout.
  3. Common board elements — logo/title, menu, welcome bar, stats, footer, breadcrumbs.
  4. Main tables — forum and topic lists.
  5. Main posts / main forms / profiles.
  6. Colour schemeall colours are gathered at the bottom of the file, so re-colouring Carbon means editing one contiguous section rather than hunting through the layout rules.
  7. New-post indicator — the unread bubble, drawn with a CSS mask over img/icon-newpost.svg and driven by custom properties (--newpost-icon, --newpost-color-new, --newpost-color-read, --newpost-icon-size) so a theme can restyle it without new images.
  8. Carbon tweaks — rounded corners and polish.
  9. Responsive layer — a single @media (max-width: 720px) block (see below).

Asset URLs in the CSS are relative to the style/ directory: url(Carbon/img/bull.png) reaches the style's own images, url(../img/icon-newpost.svg) reaches the shared board img/.

The markup a style targets

eveBB's HTML is stable, semantic, and heavily classed — everything below comes from the templates in include/template/ plus header.php/footer.php.

Page skeleton

Every page body is

<div id="pun<page>" class="pun">

where <page> is the script name — so you can scope rules per page: #punindex, #punviewforum, #punviewtopic, #punpost, #punedit, #punsearch, #punprofile, #punmisc, #punhelp, #punadmin, #punredirect, and so on. Nearly every selector in Carbon is prefixed with the .pun namespace class.

Inside:

.top-box
.punwrap                      ← the outer card frame
  #brdheader.block > .box
    #brdtitle.inbox           ← <h1> board title, or #brdlogo (logo image)
      #brddesc                ← board description
    #brdmenu.inbox > ul > li  ← main nav: #navindex #navuserlist #navrules
                                #navsearch #navregister #navlogin
                                #navprofile #navadmin #navlogout
                                (active item has class="isactive")
    #brdwelcome.inbox         ← status line (ul.conl) + quick searches (ul.conr)
  #announce                   ← optional announcement banner
  #brdmain                    ← the page content
  #brdfooter.block > .box     ← #modcontrols #brdfooternav #poweredby
                                #copyright #qjump #feedlinks #searchlinks
.end-box

Logo positioning adds one of the classes brdlogo-left, brdlogo-center, brdlogo-right, brdlogo-full, brdlogo-cover on the logo block.

The two core content patterns

Topic/forum tables — .blocktable. .blocktable > .box > table, with column cells classed .tcl (the wide left column; forum/topic names sit in .tclcon > h3), .tc2/.tc3 (narrow count columns), .tcmod, and .tcr (the right "last post" column). Rows with unread posts carry .inew; the status square is .icon — in Carbon it's the masked bubble described above. The small last-poster avatar on the index is .lastpostavatar img (32×32).

Posts — .blockpost. Each post is .blockpost > h2 (the header bar) plus .inbox, which contains a fixed 194-px-wide author sidebar .postleft/.postfootleft (username in dt strong, .usertitle, .postavatar img at 90×90 with object-fit: cover) with the message floated against it: .postright > .postmsg, plus .postsignature, .postedit, .usercontacts. Quote boxes are .quotebox (with a cite attribution line); code boxes are .codebox (rendered dark in Carbon, and pinned direction: ltr so code stays readable on RTL boards).

Forms and two-column pages

Forms live in .blockform > .box, grouped as .inform > fieldset > legend + .infldset, with info panels .forminfo, error boxes #posterror / .error-info / .error-list, button rows .buttons, and the required-field asterisk on .required strong. Profile and admin pages are two-column: a floated .blockmenu menu (13 em) beside .block2col content; the active menu item is .isactive. The admin console body is #adminconsole, with #adintro, #adstats, #adalerts and the red "differs from default" permission cells .nodefault.

Utility classes you'll meet everywhere: .conl / .conr (float left/right), .clearer, .clearl, .clearb, .inbox, .box, .hd.

Responsive behaviour

The bundled mobile layout is pure CSS: one @media (max-width: 720px) block at the end of Carbon.css. It shrinks page padding, unfloats the welcome/stats columns, hides the .tc2/.tc3 count columns in tables, collapses the post author sidebar into a compact strip above the message (with a 56 px avatar), and makes forms, textareas, and the editor full-width. A comment above the block invites style authors to copy it as a starting template.

header.php emits <meta name="viewport" content="width=device-width, initial-scale=1" /> on all non-admin pages; the admin console intentionally keeps its desktop layout.

There are no print styles and no JavaScript-driven breakpoints.

RTL languages

The <html> element carries dir="<direction>" from the active language pack (lang_direction in the pack's common.php, 'ltr' for English; a pack can declare 'rtl'). Carbon itself is written left-to-right and does not ship mirrored [dir=rtl] rules — a fully mirrored theme would add its own.

Template overrides

Page chrome comes from five templates in include/template/: main.tpl (all normal pages), admin.tpl (admin console), help.tpl, maintenance.tpl, redirect.tpl. A style may override any of them by placing a same-named .tpl file in its style/<Name>/ folder — header.php prefers the style's copy.

Templates are plain HTML with <pun_...> placeholder tags that the core substitutes at render time:

Tag Replaced with
<pun_language> / <pun_content_direction> language identifier / ltr|rtl
<pun_head> the entire <head> payload (title, stylesheet links, editor assets)
<pun_page> the sanitized page name (used in id="pun<page>")
<pun_title> / <pun_desc> board title (or logo) / description
<pun_navlinks> / <pun_status> main menu / welcome bar
<pun_announcement> announcement banner (or nothing)
<pun_main> the page body
<pun_footer> the footer block
<pun_include "file"> includes a file
<pun_maint_main> / <pun_redir_main> body of the maintenance / redirect pages

Most styles never need template overrides — the CSS hooks above are usually enough.

Creating a style, step by step

  1. Copy Carbon: cp style/Carbon.css style/MyStyle.css && cp -r style/Carbon style/MyStyle (also copy any Carbon/img references — search your new CSS for Carbon/ and change the paths to MyStyle/).

  2. Edit style/MyStyle.css. For a re-colour, start at the colour scheme section at the bottom; for layout changes, work through the earlier sections.

  3. Your style now appears automatically in Profile → Display and Administration → Options. Style file names must consist of letters, digits, underscores, and hyphens, starting with a letter or digit (at most 64 characters) to be manageable from the admin Styles page.

  4. Optionally add style/MyStyle/base_admin.css (start from style/imports/base_admin.css or Carbon's) if you want the admin console themed too.

  5. Optionally add a manifest so the admin Styles page shows proper metadata — style/MyStyle/style.json:

    {
      "name": "My Style",
      "slug": "MyStyle",
      "version": "1.0",
      "author": "You"
    }

    name, slug, and version are required in a manifest; the slug must match the folder/file name exactly.

Distributing a style

Package it as a zip containing a single top-level folder named after the slug, holding style.json, <slug>.css, and any assets:

MyStyle.zip
└── MyStyle/
    ├── style.json
    ├── MyStyle.css
    ├── base_admin.css        (optional)
    └── img/...

Administrators install it via Administration → Styles → Upload a style; the installer validates the manifest, checks every zip entry against path-traversal tricks, and explodes the archive into the classic style/MyStyle.css + style/MyStyle/ layout. The Styles page can also set any style as the board default or delete styles (never the default, never the last one).

FluxBB 1.5 styles use the same single-CSS-file convention and generally work when copied into style/ — check image paths and add the responsive block if you want them usable on phones.

Clone this wiki locally