Puzzle.js Reference: Styling

Note: while Puzzle.js puzzles store their state locally (via localStorage), that behavior is inhibited on this page to make it easiest to see exactly what markup produces exactly what result.

Important Forward Compatibility Note

Puzzle.js is very much a work in progress, and may change over time to support a wider breadth of scenarios. This evolution may alter some of the ways that things can be styled.

When a change occurs that is likely to break any existing custom styling, it will be called out in the Breaking Changes section, along with migration advice.

Basic Color Styles: always forward-compatible

For styling that is guaranteed to never break, use the styles in puzzle-basic-colors.css, which are limited to color changes. This file defines fill classes for white, lightgray, darkgray, black, red, orange, yellow, green, blue, indigo, and violet.

puzzle-basic-colors.css also provides fill classes that support interior paths of many colors on a black background, via white-laser, red-laser, orange-laser, yellow-laser, green-laser, blue-laser, indigo-laser, and violet-laser.

Text properties: always forward-compatible

Standard changes to text properties should always be compatible, with the possible exception of font-size.

Size

Cell size can currently be changed simply by setting the CSS variable --puzzle-cell-size on a puzzle. If the cells contain text, you may also want to change the font-size property to increase or decrease the font size, as well as for .small-text. That said, font sizes will scale by default along with cell size.

Text

Text comes with an outline by default to make sure that it is legible on top of anything no matter how dark. If the outline is not desired for any reason, it can be removed by setting text-shadow to none.

Text properties for cells with given letters can easily be changed, as well as background properties of those cells. However, background properties will likely conflict with the data-fill-classes option, if that option is also used.

Fills

Fills can be more than just colors; they can be any bitmap or SVG file as well, via the standard CSS properties for such.

The fills that are specified in data-fill-classes can change more than just colors, and do not have to even change the background at all. In addition, given-fill can be used to give special marking to the cells with givens. Finally, the fill class can also be used to color paths or edges.

If the fill contains a special symbol provided by ::before or ::after, it can be centered with an absolute-positioning trick, as follows:

The absolute-positioning trick can also be used to put such pseudoelements above path lines, along with a z-index change.

If the special symbol includes emoji, you may need to slightly tweak the positioning to get it to center vertically, like the 45% below.

Paths, Edges, and Spokes

Since paths, edges, and spokes are made with SVG, they must be styled with the stroke property, not the border property.

Custom Paths

There are three path styles provided for the data-path-style option: straight, curved, and track. If something else is desired, you can provide your own SVG file; when the value of data-path-style ends with .svg, it will find that SVG file relative to your page. It should be structured like this:

This SVG is composed of five superimposed elements, and the appropriate components will be referenced with the SVG use element. These elements are single path elements in the example above, but can be groups of elements so long as a parent g element has the appropriate id attribute.

Note that no stroke property is present in the SVG, so that the uses of the SVG can override that.

Custom Edges

Edges describe both the initial bounding box and the edges that go within it. There are four edge styles provided for the data-edge-style option: box, dash, dots, and none. If something else is desired, you can provide your own SVG file; when the value of data-edge-style ends with .svg, it will find that SVG file relative to your page. It should be structured like this:

This SVG is composed of nine superimposed elements, and the appropriate components will be referenced with the SVG use element. Most of these elements are single path elements in the example above, but can be groups of elements so long as a parent g element has the appropriate id attribute.

Note that no stroke property is present in the SVG, so that the uses of the SVG can override that.

Remember that edges are shared between cells, and the right and bottom edge elements will only be used for the right and bottom edges of the grid.

Custom Spokes

Spokes describe lines that can go in up to 8 directions from any cell. They are similar to paths, except that due to the larger number of angles and intersections, the styling possibilities are more limited. There are two spoke style provided for the data-spoke-style option: solid and dash. Additionally, double spokes are provided in the 4 cardinal directions and correspond to spoke-levels = 2.

If something else is desired, you can provide your own SVG file; when the value of data-spoke-style ends with .svg, it will find that SVG file relative to your page. Spoke levels up to 15 are supported for both spoke-n and spoke-ne, with the levels cycling in order. It should be structured like this:

This SVG is composed of at least six superimposed elements, and the appropriate components will be referenced with the SVG use element. Most of these elements are single path elements in the example above, but can be groups of elements so long as a parent g element has the appropriate id attribute.

Note that no stroke property is present in the SVG, so that the uses of the SVG can override that.

Layers

If the effect you want is difficult to create with just one grid, consider using two or more overlapping grids and set data-no-input on all but one to remove them from tab order etc. The overlapping puzzles will not share any information with each other. You could of course also use a background image or SVG.

Commands

Commands can be moved from their default bottom placement by modifying the puzzle-entry and/or puzzle-commands styles.

CSS Variables

These CSS variables can be set in a CSS rule on a puzzle. The CSS rules may also be modified through JavaScript.

VariableMeaning
--puzzle-cell-sizeThe size of a single cell of the grid. This variable will control both the cell height and the cell width. If you want cells to be rectangular, set the CSS width property in a rule with the .puzzle-entry .cell selector as well as setting the --puzzle-cell-size variable in a rule with the .puzzle-entry selector.

Many Helpful CSS Selectors

This is certainly not an exhaustive list of selectors, but it includes nearly all classes that PuzzleJS sets on output elements.

SelectorSelects
.puzzle-entryThe root of the puzzle, which includes the content and the commands, if requested
.puzzle-entry-contentThe content of the puzzle, which includes the grid and any other content placed in the puzzle-entry
.puzzle-gridThe puzzle grid itself.
.cellA cell of the puzzle grid: interior, exterior, etc.
.cell.inner-cellA cell of the main (interior) area of the puzzle grid.
.cell.unselectableA cell that has no border and can’t be selected.
.cell.interestingA cell that has been marked by the player as “interesting”.
.cell.strikethroughA cell containing a clue that the player has marked as complete.
.cell.extractA cell that has been marked for answer letter extraction via # in data-text.
.cell.outer-cellA cell outside the grid, such as an exterior clue.
.cell.black-cellA black square of a crossword.
.cell .textThe text container of a cell.
.cell.small-textA cell that has small text (holding a rebus clue or candidate values).
.cell[data-path-code]:not([data-path-code="0"])A cell that contains an interior path.
.cell.given-textA cell with (uneditable) text that was provided directly in the data-text option.
.cell.given-fillA cell with (uneditable) fill that was provided directly in the data-fills option.
.cell .pathThe path between cells, if that path is present.
.cell .edge-baseThe basic bounding-box/dots/etc that surrounds a cell.
.cell[data-edge-code]:not([data-edge-code="0"])A cell that has an edge present.
.cell .edge-topThe edge above the cell, if that edge is present.
.cell .edge-bottomThe edge below the cell, if that edge is present.
.cell .edge-leftThe edge to the left of the cell, if that edge is present.
.cell .edge-rightThe edge to the right of the cell, if that edge is present.
.cell[data-x-edge-code]:not([data-x-edge-code="0"])A cell that has an X present on one of its edges.
.cell .x-edge-topThe X above the cell, if that X is present.
.cell .x-edge-bottomThe X below the cell, if that X is present.
.cell .x-edge-leftThe X to the left of the cell, if that X is present.
.cell .x-edge-rightThe X to the right of the cell, if that X is present.
.cell .spokeAny of the 8 spokes emanating from a cell, if present.
.cell .x-spokeAny of the 8 "no" spokes emanating from a cell, if present.
.cell .spoke-2Any of the 4 double spokes emanating from a cell, if present.
.cell .clueThe interior (e.g. crossword) clue of a cell.
.cell.hoveredA crossword cell when the player is hovering over one of that cell’s crossword clues.
.cell.markedA crossword cell when one of that cell’s clues is selected.
.crossword-clues li.markedA crossword clue that is selected.
.corner-focusThe corner-focus marker, when it has focus.
.puzzle-commandsThe row of commands below the puzzle, if the data-show-commands option is set.
.puzzle-about-buttonThe About button, if the data-show-commands option is set.
.puzzle-undo-buttonThe Undo button, if the data-show-commands option is set.
.puzzle-redo-buttonThe Redo button, if the data-show-commands option is set.
.puzzle-reset-buttonThe Reset button, if the data-show-commands option is set.

Breaking Changes

Cell sizing is now controlled best from a --puzzle-cell-size CSS variable set on the puzzle, rather than by the width and height properties of a cell.