8 colours · 4px gridP · 16 / 26Press start

P · 16 / 26

P — Pixelart

Every square placed by hand.

The style

Every square, on purpose.

Every picture on a screen is made of pixels. Pixel art is the choice to let you see them, and to place each one by hand. It began as a limit. Tomohiro Nishikado’s Space Invaders, in 1978, drew its aliens a few squares wide because that was what the hardware could hold.

The Famicom, launched in Japan in 1983, allowed a sprite three colours and a clear one, and no more than eight sprites on a line. Artists learned to suggest a face in a handful of pixels. A year later Susan Kare drew the first Macintosh icons on graph paper, 32 squares a side, and showed that a tiny grid could feel friendly rather than crude.

The limits are gone now, and pixel art stayed. PICO-8, a “fantasy console” from 2015, sets its games on a 128-pixel screen with sixteen colours, by choice. The style is the limit, kept on purpose.

The rule: one pixel size, one small palette, nothing between two pixels.

In use

A night in the keep.

Lantern Keep, floor 2. A small game screen built from the kit below: walk Wren’s pack with the arrow keys, open the chest and fill the lantern. Health and magic fill in cells, and the keeper’s lines type out.

Lantern Keep · Floor 2QuestOpen the chestGold120
Keeper

Keeper: Late again, Wren. The lantern on the north wall is out.

WrenLv 7 · Lamplighter
HP34/52MP8/20EXP216/360

Pack

7 / 16
Potion× 2

Red, and warm in the hand. Restores 20 HP.

  1. One pixel, four of yoursEvery sprite is drawn on its own small grid and shown at a whole multiple: one art pixel, four screen pixels. Nothing is scaled by a fraction, so no edge goes soft.
  2. Eight colours, all of itThe keep, Wren, the items and the interface share one palette of eight. Health turns from green to yellow to red without a ninth colour.
  3. States in framesA bar fills a cell at a time, a press drops 4px, the dialogue types out. Nothing eases. Pause stops every loop, and the typing is instant when your system asks for less motion.
The kit

Every part, on the grid.

The parts that screen is built from, in every state. Each tile names what it is drawn with. The rows of states hold still for comparison; everything else works.

Button

4px depth
DefaultHoverPressedFocusDisabled
Pressed sinks 4px into its own depth band.

Text field

block caret
EmptyFocusErrorDisabled
0 / 6

Select

▶ cursor
OpenDisabled

Switch, checkbox, radio

2 frames
Text speed

Slider

10 cells
7 / 10
Disabled
Ten steps, one cell each. Nothing between.

Progress

steps(6)
HP44%Low10%Saving66%Now loading…

Segments and tabs

lifted
Lv 7. Attack 18, defence 11, speed 9.

List rows

▶ cursor

Card and loading

dither
QuestThe north lantern

Find the oil, light the lamp. Reward: 40 gold, 144 EXP.

1 of 2 steps
QuestSlimes in the cellar

Three of them, and the cook wants her cellar back.

Loading is a dither that crawls two pixels a beat, never a soft glow.

Toast

steps(3)

Modal

window

Save game

Steps

map nodes
  1. Gate, cleared
  2. Hall, cleared
  3. Keep, you are here
  4. 4Tower, not yet

Badges and avatars

16 × 16
NewLv 7× 3Rare
  • Wren, ready
  • Keeper, resting
  • Slime, knocked out
Portraits are the sprites, never a photo.
Signature

Draw your own sprite.

Sixteen by sixteen, on the page’s eight colours. Draw two frames with pencil, fill and mirror, watch them walk in the preview, and download both as one PNG, scaled up with every pixel kept square.

Row 8, column 8: Red

Frame
Preview
Frames 1 and 2, actual size × 4

Your system asks for less motion, so the preview holds frame 1. Both frames are side by side above it.

Start from

Tokens

The system, in numbers.

Eight colours and one grey for quiet text, the grid every size comes from, two faces, and the motion, all in steps. Copy them as custom properties, with the frame, the button and the meter.

Colour
  • --night #0d1030The ground; outlines and eyes
  • --navy #1d2b53Windows, cards, floors
  • --plum #7e2553Depth under buttons; wood, stone
  • --green #00e436Health, on, done, 10.7:1
  • --blue #29adffMagic, fields, links, 7.5:1
  • --red #ff004dDanger and low health, 4.7:1
  • --yellow #ffec27Cursor, focus, gold, 15.2:1
  • --cream #fff1e8Text and frames, 16.8:1
  • --mist #a9b4d6Quiet text only, never in a sprite, 9.0:1
Grid
  • Art pixel4pxSprites at 4×; frames, depth, gaps
  • Small art2pxGlyphs in text: the cursor, the arrow
  • Tile8 art pxItems and map tiles
  • Sprite16 art pxPeople, slimes, chests
TypeAa 8pxDisplay · Press Start 2P · 8, 10, 12px and up by 8. Titles and short labels only.Aa, set to readText · Pixelify Sans · 15 to 19px. Everything people read.
Motion
  • PressinstantDown 4px; the depth band goes
  • Fill0.36s steps(6)Meters, a cell at a time
  • Walk2 frames, 0.9sIdle sprites; pausable
  • Type28ms a letterDialogue; instant if reduced
  • Blink1.2s steps(1)Cursors; under 1 a second

No easing anywhere: steps() or instant. Loops pause with one button and stop for reduced motion.

:root {
  /* Eight colours. Sprites use these and nothing else. */
  --night: #0d1030;
  --navy: #1d2b53;
  --plum: #7e2553;
  --green: #00e436;
  --blue: #29adff;
  --red: #ff004d;
  --yellow: #ffec27;
  --cream: #fff1e8;
  /* One grey for quiet text, never inside a sprite. */
  --mist: #a9b4d6;

  /* One art pixel. Everything is a whole multiple. */
  --px: 4px;
  --font-display: 'Press Start 2P', monospace;
  --font-text: 'Pixelify Sans', monospace;
}

/* Hard edges whenever an image is scaled. */
canvas, img.sprite {
  image-rendering: pixelated;
}

/* A frame: one shadow per side, so each corner is a missing pixel. */
.frame {
  --b: var(--cream);
  box-shadow:
    0 calc(var(--px) * -1) 0 var(--b),
    0 var(--px) 0 var(--b),
    calc(var(--px) * -1) 0 0 var(--b),
    var(--px) 0 0 var(--b);
}

/* A button with a depth band; pressing drops it into the band. */
.button {
  --face: var(--yellow);
  background: var(--face);
  color: var(--night);
  box-shadow:
    0 -4px 0 var(--face), -4px 0 0 var(--face),
    4px 0 0 var(--face), 0 4px 0 var(--face),
    0 8px 0 var(--plum);
}
.button:hover { --face: var(--cream); }
.button:active {
  transform: translateY(var(--px));
  box-shadow:
    0 -4px 0 var(--face), -4px 0 0 var(--face),
    4px 0 0 var(--face), 0 4px 0 var(--face);
}

/* A meter in cells, filled one cell at a time. */
.meter-fill {
  clip-path: inset(0 calc(100% - var(--value)) 0 0);
}
@media (prefers-reduced-motion: no-preference) {
  .meter-fill { transition: clip-path 0.36s steps(6, end); }
}

Do

  • Pick one pixel size and keep it. Every sprite, border and gap is a whole multiple of the same unit.
  • Choose a small palette first and draw everything from it, interface included.
  • Scale only by whole numbers, with smoothing off, so every pixel stays square.
  • Set reading text in a pixel face built to be read, and keep the blocky display face for short labels.

Don’t

  • Don’t mix pixel sizes

    A sprite at 4× beside one at 3× and a border at 1× breaks the grid that makes the style. Pick one unit for the whole screen.
  • Don’t scale it smooth

    Resized with smoothing, pixel art goes soft and grey at every edge. Turn it off with image-rendering: pixelated, and scale by whole numbers.
  • Don’t sneak in gradients

    A soft gradient or a blurred shadow on a sprite reads as a mistake, not a style. Shade with a few flat steps from the palette.

In the wild

Where the style shows up outside this page.

  1. 1978

    Space Invaders

    Tomohiro Nishikado, TaitoAliens in two frames of a few dozen pixels, readable at a glance.
  2. 1984

    Macintosh icons

    Susan KareThe trash can, the happy Mac: whole ideas in 32 by 32 squares.
  3. 1985

    Super Mario Bros.

    NintendoA moustache and a cap, because there were too few pixels for a mouth and hair.
  4. 2018

    Celeste

    Maddy Thorson, Noel BerryPixel art today: a small palette, big screens, every pixel still placed.