Dark mode
In Bulma 1.0 dark mode is built in and switches on by itself: if the user's system uses a dark appearance, a page with Bulma turns dark too. You do not need to do anything — background, text, cards, fields and tables change colour together. Your job is not to break this with your own colours and, if you like, to give users a choice.
How it works
All Bulma colours are stored in CSS variables. The stylesheet contains two sets of values: one for the light theme and one for the dark theme. The set is chosen by the prefers-color-scheme media query, which reports the theme the user picked in the system. Switch your system to dark mode and reload any page with Bulma — it goes dark.
Forcing a theme
The data-theme attribute or the theme-dark / theme-light class selects a theme regardless of the system. On the <html> tag they apply to the whole page:
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
</head>
<body>
<section class="section">
<h1 class="title">Wine list</h1>
<div class="box">Chianti Classico — €32</div>
<button class="button is-primary">Order</button>
</section>
</body>
</html>A dark background, a light heading, a dark grey box and a turquoise button — even if the system uses the light theme. The value data-theme="light" does the opposite and pins the light theme.
A theme for part of the page
You can put the theme-dark class on any block, and the Bulma elements inside it turn dark:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<div class="columns is-mobile">
<div class="column theme-light">
<div class="box">Lunch: a light card</div>
</div>
<div class="column theme-dark">
<div class="box">Dinner: a dark card</div>
</div>
</div>Two cards side by side, one light and one dark. The block with the class gets no background itself — it is the box inside that turns dark.
A toggle button
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<section class="section">
<button class="button" id="theme-toggle">Switch theme</button>
<div class="box mt-4">Trattoria Oliva — open from 12:00.</div>
</section>
<script>
const root = document.documentElement;
document.getElementById('theme-toggle').addEventListener('click', () => {
const isDark = root.dataset.theme
? root.dataset.theme === 'dark'
: matchMedia('(prefers-color-scheme: dark)').matches;
root.dataset.theme = isDark ? 'light' : 'dark';
console.log('Theme:', root.dataset.theme);
});
</script>Each click changes data-theme on <html>, the page switches between the light and dark themes, and the name of the new theme appears under the example. Until the attribute is set, the current theme comes from the system setting, which matchMedia reads. To keep the choice between visits, save it to localStorage and read it on load.
If you do not want dark mode
Use the build without it: https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/versions/bulma-no-dark-mode.min.css. Or put data-theme="light" on <html>.
Common mistake
Setting colours in your CSS with fixed values: .price { color: #333; }. In the dark theme such text almost vanishes against the dark background. Use Bulma's variables, which change with the theme: color: var(--bulma-text-strong) or background: var(--bulma-scheme-main).