Skip to content

Stylesheet (CSS)

All CSS rules for your game should be stored in a file called <yourgamename>.css at the root of your project folder.

General rules

The CSS has three main responsibilities:

  • Define the layout of your game
  • Define the rules for image sprites
  • Set a thematic background

Use of drop-shadow

Drop shadows can look nice, but they currently cause significant performance issues in Safari, especially if you have more than one on the page at once. Consider these alternatives:

  • Use box-shadow instead. This works for rectangular elements, including those with rounded corners, and circles (border-radius: 50%).
  • Bake the shadow into the image. The WebP image then contains the shadow, so no CSS shadow is needed.
  • Disable drop-shadow in Safari using the dj_safari class, which is automatically added to the document.
`drop-shadow` disabled for Safari only
.game-element {
    filter: drop-shadow(3px 3px 4px rgba(0,0,0,0.7));
}    
.dj_safari .game-element {
    filter: none;
}

Examples

Setting a thematic background for the game

Thematic background
body {
    background: url('img/background.webp'), #f2f2f2;
}
See the Dark mode support section to use different backgrounds depending on the theme.

Default BGA background

The default BGA background is set on the html element, so a background set on the body element will cover it.

Layout

Example: display all player tables in a centered column
#player-tables {
    display: flex;
    gap: 10px;
    flex-direction: column;
    align-items: center;
}

Single-row sprite

Example: sprite in an image
.disc {
    position: absolute;
    width: 54px;
    height: 54px;
    background-image: url('img/discs.webp');
    background-size: auto 100%;
}
.disc[data-side="white"] { 
    background-position-x: 0%;
}
.disc[data-side="black"] { 
    background-position-x: 100%; 
}
Disc example

In this example, <div class="disc" data-side="white"></div> will display a white disc, and changing the data-side attribute to black will show the black disc from the same sprite.

Card sprite

Example: card sprite with 4 rows of 10 cards
.card {
    position: absolute;
    width: 100px;
    height: 200px;
    background-image: url('img/cards.webp');
    background-size: 1000% 400%;
    background-position-x: calc(var(--card-column) * 100% / 9);
    background-position-y: calc(var(--card-row) * 100% / 3);
}

In this example, <div class="card" style="--card-row: 0; --card-column: 2;"></div> will display the third card in the first row (using zero-based indices).

Maximum sprite size

Images should be no larger than 4096 × 4096 pixels. See the Game art section for more details.

Dark mode support

BGA supports dark mode natively. Players can toggle it by clicking on their avatar before starting a game or opening the hamburger menu in the top-right corner during a game. When dark mode is enabled, BGA adds the data-theme="dark" attribute to the html element. Use the [data-theme="dark"] selector to override the default light styles when the player enables dark mode.

Different backgrounds for light and dark themes
body {
    background: url('img/light-background.webp'), #f2f2f2;
}
[data-theme="dark"] body {
    background: url('img/dark-background.webp'), #1d1d1d;
}
Change the player panel color in light mode only
[data-theme="light"] .player-board {
    --game-bga-player-panel-background: white;
}

Use this selector instead of @media (prefers-color-scheme: dark), because the media query relies on the browser settings and ignores the BGA toggle.

If you don't have a separate image for dark mode, you can try this:

Modify the background with a CSS rule
[data-theme="dark"] body {
  background-blend-mode: color-burn;
}
Use your browser's developer tools to try different values for this property and find the one that works best with your base image.

Migrating

Most games work in dark mode out of the box. A common problem occurs when a game sets a fixed light background color for an element without setting its text color. This works in light mode, but in dark mode it can result in light text on a light background. Adding color: black; to elements with a fixed light background fixes this issue in dark mode and continues to work in light mode.

Use the extension’s existing styles to migrate

The BGA extension already overrides the data-theme attribute based on the user’s choice in the extension.

To add dark mode support to your game, check the extension’s source code for the CSS it currently applies to your game. You can integrate these styles into your game’s code to make them available to all players, including those who do not use the extension.

Example of a background option compatible with dark mode

If you have both light and dark backgrounds and want an automatic setting that follows the selected theme, you can add this user preference:

gamepreferences.json
    "103": {
        "name": "Background",
        "values": {
            "0": {
                "name": "Automatic"
            },
            "1": {
                "name": "Light"
            },
            "2": {
                "name": "Dark"
            }
        },
        "default": 0
    }

Then in the CSS:

yourgamename.css
[data-theme="light"] body[data-background="0"], body[data-background="1"] {
  background: url('img/background-light.webp');
}
[data-theme="dark"] body[data-background="0"], body[data-background="2"] {
  background: url('img/background-dark.webp');
}

If you have this.bga.userPreferences.onChange = (prefId, prefValue) => this.onUserPreferenceChanged(prefId, prefValue); or something similar in your setup, add the following code to the callback so that the body element’s data-background attribute updates as soon as the user preference changes:

modules/js/Game.js
    /**
     * @param {number} prefId
     * @param {number} prefValue
     */
    onUserPreferenceChanged(prefId, prefValue) {
        switch (prefId) {
            case 103:
                document.body.dataset.background = `${prefValue}`;
                break;
        }
    }

Using SCSS

You can use SCSS to split your CSS rules into multiple files and use features such as nested rules and loops.

To use SCSS, rename src-disabled to src and write your SCSS rules in the src/scss folder. The build setup will generate yourgamename.css for you. See the VSCode setup page to configure automatic builds when you save SCSS files.