A comprehensive chess board component with support for piece rotation, fairy chess notation, keyboard navigation, and interactive editing. Perfect for chess problem compositions, position analysis, and chess applications.
Shift to clone while moving, or Ctrl
to clone and invert the colorfen attribute for either standard FEN or
FFEN input, with automatic format detectionClick on the board below to select a square, then try these keyboard shortcuts:
Shift while moving to clone; hold Ctrl to clone and
invert the colordisabledWhen the disabled attribute is set, the chess board will not respond to any user interactions.
This is useful for displaying a static position or preventing changes during analysis.
<chess-board />
auto-select-piece-on-clickWhen the auto-select-piece-on-click attribute is set,
clicking on a square with a piece will automatically select it.
Clicking on an empty square will move the selected piece there.
<chess-board />
💡 Tip: Focus the board and experiment with all keyboard shortcuts to see the component in action!
The chess board automatically adapts to its container size while maintaining a minimum size of 200px × 200px. The font size scales with the board using CSS Container Queries.
This board demonstrates how to customize the chess board colors using CSS custom properties. The
gray-board class applies gray tones instead of the traditional brown colors. You can customize the
board appearance by setting CSS variables like --cb-chess-light-square,
--cb-chess-dark-square, --cb-chess-border-color, and
--cb-chess-label-color.
This board demonstrates a warm wood aesthetic perfect for a traditional chess experience. The
wood-board class applies rich brown tones reminiscent of walnut and maple wood. The light squares use
a honey-colored tone (#f4d7a8) while dark squares feature a deep brown (#8b5a2b), creating an elegant wooden chess
board appearance. Custom CSS variables provide full control over the wood coloring with
--cb-chess-light-square, --cb-chess-dark-square, --cb-chess-border-color,
and --cb-chess-label-color.
This board automatically rotates 180 degrees when it's black's turn to move, based on the FEN string. The rotation provides a better viewing experience for the player whose turn it is. Compare this with the board above where white is to move.
The chess board dispatches a cellMainClick event when the main mouse button is used on a square, and
also emits the legacy cellClick alias for backward compatibility. The event detail contains the
square
coordinate and piece information including rotation and fairy notation (if present). Click on any square below to
see the event details.
// Listen for cell click events
const board = document.getElementById('clickable-board');
const output = document.getElementById('click-output');
board.addEventListener('cellClick', (event) => {
const { square, piece } = event.detail;
if (piece) {
let info = `Clicked ${cell} - ${piece.color} ${piece.type}`;
if (piece.rotation) info += `, rotation: ${piece.rotation}°`;
if (piece.fairyName) info += `, fairy-name: ${piece.fairyName}`;
if (piece.fairyCondition) info += `, fairy-condition: ${piece.fairyCondition}`;
output.textContent = info;
} else {
output.textContent = `Clicked ${cell} - Empty square`;
}
});
The chess board supports comprehensive keyboard navigation. Click on the board below and try these keys:
Every time the board position changes — via keyboard, mouse click, or programmatic API — the
current position is recomputed and exposed through getFen(). The component accepts
either a standard FEN string or a fairy-aware FFEN string through the same fen
attribute, and it auto-detects the format so you do not need separate state or duplicate APIs.
FEN follows the standard Forsyth-Edwards Notation and is lossy: it keeps the board structure but drops specialized fairy metadata. FFEN extends the same format with fairy-aware metadata when needed, and the board preserves that information automatically when the input contains it.
Interact with the board below (add/delete/move pieces) and watch the string update in real time.
const board = document.getElementById('fen-sync-board');
// Called automatically after every board change
console.log(board.getFen());
// → "r1bqkb1r/pp3ppp/2np1n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w - - 0 1 e4:gn:Chameleon"
// Monitor current square selection
const keyboardBoard = document.getElementById('keyboard-board');
const selectionOutput = document.getElementById('selection-output');
// Update display when selection changes
setInterval(() => {
const current = keyboardBoard.getCurrentSquare();
selectionOutput.textContent = current ? `Selected: ${current}` : 'No selection';
}, 100);
// Keyboard shortcuts available:
// Navigation:
// - Arrow keys: Navigate between squares
// - Click: Select square
//
// Piece management:
// - Delete: Remove piece from current square
// - Escape: Clear board
// - Shift+Escape: Reset to starting position
// - P/R/N/B/Q/K (uppercase): Add white pieces
// - p/r/n/b/q/k (lowercase): Add black pieces
// - E/T/A (uppercase/lowercase): Add fairy pieces
//
// Piece rotation:
// - Alt/Option+Left: Rotate counter-clockwise 45°
// - Alt/Option+Right: Rotate clockwise 45°
// - Alt/Option+Up: Reset rotation to 0°
// - Alt/Option+Down: Set rotation to 180°
//
// Board orientation:
// - Shift+Up: White perspective
// - Shift+Down: Black perspective
Use Space or Enter to select and move pieces on the board:
💡 Tip: Try this workflow:
The chess-piece component supports rotation (0-315° in 45° steps) and fairy chess notation for
problem compositions. Use the rotation attribute for piece rotation, fairy-name for
top-left annotation (max 3 chars), and fairy-condition for bottom-right annotation.
0°
45°
90°
135°
180°
225°
270°
315°
Empress with name
Amazon with condition
Neutral Angel
Rotated with notation
The chess-piece component allows you to display individual chess pieces. Use the piece
attribute for standard, fairy, or symbolic types (k, q, r, b, n, p, e, t, a, c, s, x, or a supported
fairy-letter/number type) and the color attribute for white, black, or neutral pieces (w, b, n).
This example shows how to add pieces to the empty board programmatically.
// Example: Add pieces to create a starting position
document.addEventListener('DOMContentLoaded', () => {
const board = document.getElementById('board-with-pieces');
// Add white pieces
addPiece(board, 'e1', 'k', 'w'); // White king
addPiece(board, 'd1', 'q', 'w'); // White queen
addPiece(board, 'a1', 'r', 'w'); // White rook
addPiece(board, 'h1', 'r', 'w'); // White rook
addPiece(board, 'c1', 'b', 'w'); // White bishop
addPiece(board, 'f1', 'b', 'w'); // White bishop
addPiece(board, 'b1', 'n', 'w'); // White knight
addPiece(board, 'g1', 'n', 'w'); // White knight
// Add white pawns
for (let col = 0; col < 8; col++) {
const file = String.fromCharCode(97 + col); // a-h
addPiece(board, file + '2', 'p', 'w');
}
// Add black pieces
addPiece(board, 'e8', 'k', 'b'); // Black king
addPiece(board, 'd8', 'q', 'b'); // Black queen
addPiece(board, 'a8', 'r', 'b'); // Black rook
addPiece(board, 'h8', 'r', 'b'); // Black rook
addPiece(board, 'c8', 'b', 'b'); // Black bishop
addPiece(board, 'f8', 'b', 'b'); // Black bishop
addPiece(board, 'b8', 'n', 'b'); // Black knight
addPiece(board, 'g8', 'n', 'b'); // Black knight
// Add black pawns
for (let col = 0; col < 8; col++) {
const file = String.fromCharCode(97 + col); // a-h
addPiece(board, file + '7', 'p', 'b');
}
});
function addPiece(boardElement, square, piece, color) {
const squareElement = boardElement.shadowRoot.querySelector(`[data-coordinate="${square}"]`);
if (squareElement) {
const pieceElement = document.createElement('chess-piece');
pieceElement.setAttribute('piece', piece);
pieceElement.setAttribute('color', color);
squareElement.appendChild(pieceElement);
}
}
This example shows how to use extended FFEN.
*2q'1'2'3'4'5'6'7/'G'A'B'R'i'e'l'e/cxs''12''ABSCX/-c-x-s5/ETA-e-t-a2/KQRBNP2/eta'g'a'b2/kqrbnp2 w KQkq - 0 1 a8:GN:Imitator,h6::BlackHole
Each square has a data-coordinate attribute with standard chess notation (e.g., "e4", "a1"). You can
select specific squares using CSS selectors or JavaScript:
// Select the e4 square
const e4Square = document.querySelector('chess-board').shadowRoot.querySelector('[data-coordinate="e4"]');
// Select all squares in the 4th rank
const fourthRank = document.querySelector('chess-board').shadowRoot.querySelectorAll('[data-coordinate$="4"]');
// Select all squares in the e-file
const eFile = document.querySelector('chess-board').shadowRoot.querySelectorAll('[data-coordinate^="e"]');
to see the chess board as an image, you can use the html2canvas library to capture the current state of the chess board and render it as a canvas image. This is useful for saving or sharing the board position as an image.
// Example: Capture the chess board as an image using html2canvas
import html2canvas from 'html2canvas';
document.getElementById('snapshot').addEventListener('click', () => {
const board = document.getElementById('board-with-f-pieces');
const snapshotImage = document.getElementById('snapshot-image');
// use html2canvas to capture the board as an image
html2canvas(board).then(canvas => {
snapshotImage.src = canvas.toDataURL();
});
});