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.
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.
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
.
Standard changes to text properties should always be compatible, with the possible exception of font-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 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 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.
Since paths, edges, and spokes are made with SVG, they must be styled with the stroke
property, not the border
property.
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.
path-i
: a line running from the center to the bottom.path-l
: a line running from the top to the bottom.path-r
: a line running from the right to the bottom, making a 90-degree turn at the center.path-t
: a T junction involving the left, right, and bottom.path-x
: a four-way junction involving all four directions.Note that no stroke
property is present in the SVG, so that the uses of the SVG can override that.
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.
edge-base
: the basic bounding box of the cell.edge-top
: the top edge of the cell, when present.edge-bottom
: the bottom edge of the cell, when present.edge-left
: the left edge of the cell, when present.edge-right
: the right edge of the cell, when present.x-edge-top
: the X denoting the lack of a top edge of the cell, when present.x-edge-bottom
: the X denoting the lack of a bottom edge of the cell, when present.x-edge-left
: the X denoting the lack of a left edge of the cell, when present.x-edge-right
: the X denoting the lack of a right edge of the cell, when present.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.
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.
spoke-n
: a spoke pointing north (which will be rotated for east, south, and west).spoke-ne
: a spoke pointing northeast (which will be rotated for southeast, southwest, and northwest).x-spoke-n
: a "no" spoke pointing north (which will be rotated for east, south, and west).x-spoke-ne
: a "no" spoke pointing northeast (which will be rotated for southeast, southwest, and northwest).reticle
: an indicator for drawing spokes, that shows which direction corresponds to the up arrow.x-reticle
: an indicator for drawing "no" spokes, that shows which direction corresponds to the up arrow.spoke-n-2
: by default, a parallel set of spokes pointing north (which will be rotated for east, south, and west).spoke-ne-2
through spoke-ne-15
and spoke-n-3
through spoke-n-15
require custom SVG files.Note that no stroke
property is present in the SVG, so that the uses of the SVG can override that.
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.
Do note that a screenreader will most likely not communicate information properly when multiple puzzles are overlapped, and in this case you should set data-no-screenreader
on both puzzles when you do this.
You can also use data-extra-style-classes
and data-extra-styles
to apply a second level of CSS classes to your cells. The extra classes are read out by a screenreader, so this option is much better if you can make use of it.
Commands can be moved from their default bottom placement by modifying the puzzle-entry
and/or puzzle-commands styles.
These CSS variables can be set in a CSS rule on a puzzle. The CSS rules may also be modified through JavaScript.
Variable | Meaning |
---|---|
--puzzle-cell-size | The 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. |
This is certainly not an exhaustive list of selectors, but it includes nearly all classes that PuzzleJS sets on output elements.
Selector | Selects |
---|---|
.puzzle-entry | The root of the puzzle, which includes the content and the commands, if requested |
.puzzle-entry-content | The content of the puzzle, which includes the grid and any other content placed in the puzzle-entry |
.puzzle-grid | The puzzle grid itself. |
.cell | A cell of the puzzle grid: interior, exterior, etc. |
.cell.inner-cell | A cell of the main (interior) area of the puzzle grid. |
.cell.unselectable | A cell that has no border and can’t be selected. |
.cell.interesting | A cell that has been marked by the player as “interesting”. |
.cell.strikethrough | A cell containing a clue that the player has marked as complete. |
.cell.extract | A cell that has been marked for answer letter extraction via # in data-text . |
.cell .extract-label | The label for a cell from the data-extracts list. |
.cell.link | A cell that is linked to another cell via the data-links option. |
.cell .link-label | The label for a link from the data-links list. |
.cell.outer-cell | A cell outside the grid, such as an exterior clue. |
.cell.black-cell | A black square of a crossword. |
.cell .text | The text container of a cell. |
.cell.small-text | A 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-text | A cell with (uneditable) text that was provided directly in the data-text option. |
.cell.given-fill | A cell with (uneditable) fill that was provided directly in the data-fills option. |
.cell .path | The path between cells, if that path is present. |
.cell .edge-base | The 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-top | The edge above the cell, if that edge is present. |
.cell .edge-bottom | The edge below the cell, if that edge is present. |
.cell .edge-left | The edge to the left of the cell, if that edge is present. |
.cell .edge-right | The 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-top | The X above the cell, if that X is present. |
.cell .x-edge-bottom | The X below the cell, if that X is present. |
.cell .x-edge-left | The X to the left of the cell, if that X is present. |
.cell .x-edge-right | The X to the right of the cell, if that X is present. |
.cell .spoke | Any of the 8 spokes emanating from a cell, if present. |
.cell .x-spoke | Any of the 8 "no" spokes emanating from a cell, if present. |
.cell .spoke-2 | Any of the 4 double spokes emanating from a cell, if present. |
.cell .clue-label | The interior (e.g. crossword) clue of a cell. |
.cell.hovered | A crossword cell when the player is hovering over one of that cell’s crossword clues. |
.cell.marked | A crossword cell when one of that cell’s clues is selected. |
.crossword-clues li.marked | A crossword clue that is selected. |
.corner-focus | The corner-focus marker, when it has focus. |
.puzzle-commands | The row of commands below the puzzle, if the data-show-commands option is set. |
.puzzle-about-button | The About button, if the data-show-commands option is set. |
.puzzle-undo-button | The Undo button, if the data-show-commands option is set. |
.puzzle-redo-button | The Redo button, if the data-show-commands option is set. |
.puzzle-reset-button | The Reset button, if the data-show-commands option is set. |
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.
To be consistent with the nomenclature used for links and extracts, .clue
now refers to a cell with a clue, and .clue-label
refers to the label itself.