Monsoon v0.2.0
Made by Alexandre Kohler Star

Installation

Install Monsoon in WordPress

In WordPress, stylesheets belong in functions.php through wp_enqueue_style, never in a hard coded <link>. Enqueue Monsoon first and your theme stylesheet second, and every template can use the classes.

2 min readWordPress

Install

functions.php
<?php
add_action( 'wp_enqueue_scripts', function () {
    wp_enqueue_style( 'monsoon', 'https://cdn.jsdelivr.net/npm/monsooncss@0.2.0/dist/monsoon.min.css', array(), null );
    wp_enqueue_style( 'my-theme', get_stylesheet_uri(), array( 'monsoon' ), wp_get_theme()->get( 'Version' ) );
    wp_enqueue_script( 'my-theme-toggle', get_theme_file_uri( 'assets/js/theme-toggle.js' ), array(), wp_get_theme()->get( 'Version' ), array( 'in_footer' => true ) );
} );

add_action( 'wp_head', function () {
    wp_print_inline_script_tag( "(function(){var t;try{t=localStorage.getItem('monsoon-theme')}catch(e){}var d=t==='dark'||(t!=='light'&&matchMedia('(prefers-color-scheme: dark)').matches);document.documentElement.classList.add(d?'dark':'light')})()" );
}, 1 );

The version argument is null because the URL already pins the release; WordPress then adds no ?ver= query.

Priority 1 on wp_head prints the theme script before the stylesheets, so the class is on <html> before anything paints.

Use the classes

body_class() and post_class() accept extra classes, so Monsoon utilities sit next to the classes WordPress adds:

header.php
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>
<body <?php body_class( 'bg-background text-foreground antialiased' ); ?>>
<?php wp_body_open(); ?>
<header class="border-b">
    <div class="mx-auto max-w-5xl flex items-center justify-between px-6 py-4">
        <a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="text-lg font-semibold"><?php bloginfo( 'name' ); ?></a>
        <button type="button" id="theme-toggle" class="rounded-lg border px-3 py-2 text-sm hover:bg-muted">Toggle theme</button>
    </div>
</header>
template-parts/content-card.php
<article id="post-<?php the_ID(); ?>" <?php post_class( 'rounded-2xl border bg-surface p-6 shadow-sm space-y-3' ); ?>>
    <h2 class="text-xl font-semibold">
        <a href="<?php the_permalink(); ?>" class="hover:text-primary"><?php the_title(); ?></a>
    </h2>
    <p class="text-sm text-muted-foreground"><?php echo esc_html( get_the_date() ); ?></p>
    <div class="text-muted-foreground"><?php the_excerpt(); ?></div>
    <?php if ( is_sticky() ) : ?>
        <span class="inline-block rounded-full bg-secondary text-secondary-foreground px-2 py-1 text-xs font-medium">Featured</span>
    <?php endif; ?>
</article>

In the block editor, type classes into Advanced > Additional CSS class(es) on any block.

Dark mode

The inline script printed in wp_head sets the scheme. The button in header.php above is wired up by the enqueued toggle script:

assets/js/theme-toggle.js
const button = document.getElementById('theme-toggle');

button.addEventListener('click', () => {
  const root = document.documentElement;
  const next = root.classList.contains('dark') ? 'light' : 'dark';
  root.classList.remove('dark', 'light');
  root.classList.add(next);
  button.setAttribute('aria-pressed', String(next === 'dark'));
  try { localStorage.setItem('monsoon-theme', next); } catch (e) {}
});

wp_print_inline_script_tag() adds the attributes that a security plugin or a CSP filter asks for, which a hand written <script> in header.php would miss.

Theme with --seed

Let site owners pick the brand color in the Customizer, sanitize it, and print it as an inline style attached to the Monsoon handle:

functions.php
<?php
add_action( 'customize_register', function ( $wp_customize ) {
    $wp_customize->add_setting( 'monsoon_seed', array(
        'default'           => '#0d9488',
        'sanitize_callback' => 'sanitize_hex_color',
    ) );
    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'monsoon_seed', array(
        'label'   => __( 'Brand color', 'my-theme' ),
        'section' => 'colors',
    ) ) );
} );

add_action( 'wp_enqueue_scripts', function () {
    $seed = sanitize_hex_color( get_theme_mod( 'monsoon_seed', '#0d9488' ) );
    if ( $seed ) {
        wp_add_inline_style( 'monsoon', ':root { --seed: ' . $seed . '; }' );
    }
}, 20 );

Block themes can skip the Customizer and set :root { --seed: ... } in their own stylesheet. Every semantic token (primary, secondary, accent, surfaces, muted text, borders and the focus ring) is derived from --seed in the browser. Theming lists the tokens.

Using the purge CLI

Run it from the theme folder:

package.json
{
  "private": true,
  "scripts": {
    "css:purge": "monsooncss purge \"*.php\" \"template-parts/**/*.php\" \"inc/**/*.php\" \"parts/**/*.html\" \"templates/**/*.html\" \"assets/js/**/*.js\" -o assets/css/monsoon.css"
  },
  "devDependencies": {
    "monsooncss": "^0.2.0"
  }
}

Then enqueue the purged file on production sites only:

functions.php
<?php
$monsoon = 'production' === wp_get_environment_type()
    ? get_theme_file_uri( 'assets/css/monsoon.css' )
    : 'https://cdn.jsdelivr.net/npm/monsooncss@0.2.0/dist/monsoon.min.css';

wp_enqueue_style( 'monsoon', $monsoon, array(), null );

Classes typed into the block editor are stored in the database, not in theme files, so the purge cannot see them. On sites where editors add classes, either list them in --safelist or ship the full file.

The purge CLI reads your files as plain text and keeps every class name it can see. It cannot see a name that is assembled at runtime, so write each class in full: isActive ? 'bg-primary' : 'bg-muted' survives a purge, 'bg-' + color does not. Names that only exist at runtime (from a database, a CMS or an API) go in --safelist bg-success,bg-danger.

The purged file always keeps the reset, the theme tokens, the .dark and .light scopes and the keyframes, so dark mode and --seed keep working. See the purge CLI reference for every option.

Next steps

  • Browse every utility and its variants in the class reference.
  • Read how the scheme is chosen in Dark mode, and how tokens are derived in Theming.
  • Not using WordPress? See PHP.

Frequently asked questions

How do I see Monsoon classes inside the block editor?

Add add_theme_support( 'editor-styles' ); and add_editor_style( 'assets/css/monsoon.min.css' ); in after_setup_theme, using the bundled copy.

Can I use Monsoon in a plugin instead of a theme?

Yes. Enqueue it the same way from the plugin with plugins_url(), and give the handle a prefix so it does not clash with a theme that also loads Monsoon.

No recent searches

Try , , or .

Recent

Loading the search index

No results for ""

Check the spelling, or search a class name such as px-4.