<chess-board>

<chess-board>

A web component that renders a chess position. Put a FEN string between the tags and get a board. No framework, no stylesheet to load, one small dependency.

$ npm install chess-board
  • Standards only. A plain custom element with shadow DOM.
  • Typed. Ships TypeScript declarations for the element, squares and pieces.
  • Scriptable. Move, place and clear pieces from JavaScript.
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
The Opera Game Morphy vs. Duke Karl & Count Isouard, Paris 1858

    Every ply is one board.move(from, to) call on the same element. Castling is two calls. The last move is marked with ::part().

    Quick start

    Install, import, write markup. The element registers itself on import.

    1. Install

      The package is plain ES2022 with a single runtime dependency, fen-chess-board.

      $ npm install chess-board
    2. Import once

      Importing the module registers the <chess-board> element. Do it once, anywhere in your app.

      import "chess-board";
    3. Write markup

      The text content is the position. The piece-placement field of a FEN string is enough; the rest is ignored.

      <chess-board>
        rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
      </chess-board>

    Playground

    Toggle the attributes, paste a position, pick a colour scheme, drag the size. The markup updates as you go.

    rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
    
                
              
    Attributes
    Position
    Styling

    Colours are custom properties and squares are ::part()s; see Styling.

    Size

    The board is sized in em, so the element's font-size is the only knob.

    Styling

    The colours are custom properties and every square is a ::part(), so a page can theme the board and mark squares without touching the component.

    r1bq1rk1/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQ1RK1
    Wood, the default
    r1bq1rk1/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQ1RK1
    Green
    r1bq1rk1/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQ1RK1
    Blue
    r1bq1rk1/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQ1RK1
    Brown
    r1bq1rk1/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQ1RK1
    Print, with frame

    Colours

    Set the properties on the element or on any ancestor. Leave one out and the board keeps its default for it, so nothing changes for pages that set none.

    chess-board {
      --chess-board-light: #eeeed2;
      --chess-board-dark: #769656;
      --chess-board-border: none;
    }

    Squares

    Each square carries the parts square, its own name and its shade. Mark the last move, or the square an annotation is talking about:

    rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR
    chess-board::part(e2),
    chess-board::part(e4) {
      box-shadow: inset 0 0 0 0.15em #f0d13a;
    }
    Custom properties
    PropertyApplies to
    --chess-board-lightLight squares, #FFCE9E by default
    --chess-board-darkDark squares, #D18B47 by default
    --chess-board-borderBorder around the 8×8 board, 1px solid black by default
    --chess-board-frame-font-sizeFile and rank labels, 40% by default
    Parts
    PartElement
    boardThe 8×8 table
    squareEvery square
    a1 … h8One square
    light, darkThe squares of one shade
    frameThe file and rank labels shown by frame

    API

    Grab a mounted element with querySelector and call methods on it. Bad input throws and leaves the board untouched. Press a call to run it on this board.

    rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
    Console

      Property

      Methods

      Markup

      Attributes
      AttributeEffect
      frameShow file (a–h) and rank (1–8) labels around the board.
      reverseFlip the board so the black pieces are on the bottom.
      unicodeRender pieces as Unicode glyphs instead of the default SVGs.
      Pieces
      LetterPiece
      K Q R B N PWhite king, queen, rook, bishop, knight, pawn
      k q r b n pBlack king, queen, rook, bishop, knight, pawn

      Sizing

      The host is display: inline-block and every square is one em, so a board goes wherever text goes and scales with font-size.

      A diagram can sit right in a sentence, like this r1bqkb1r/pppp1Qpp/2n2n2/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR one, and the line height stretches to fit. Handy for annotations, commit messages rendered as HTML, or a puzzle list where every row shows its position.

      chess-board {
        font-size: 14px;
        vertical-align: middle;
      }
      1K1k4/1P6/8/8/8/8/r7/2R5
      12px
      1K1k4/1P6/8/8/8/8/r7/2R5
      22px
      1K1k4/1P6/8/8/8/8/r7/2R5
      34px with frame