Color Sort Water Puzzle with 20 Levels – HTML, CSS & JS
Color Sort Water Puzzle · Games · Plain HTML, CSS & JS · Live preview
For supporters
Source Code
Want the source code?
Play the game for free. Become a WebDevPuneet supporter to unlock the complete HTML, CSS and JavaScript source code, the exports (HTML, React, Vue, Angular, Tailwind) and Fork.
Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
Color Sort Water Puzzle — 20 Levels, Hidden Layers, a Hint Solver, Pour Animation and a Daily Puzzle

Color Sort, also known as water sort, is a puzzle where coloured liquid is poured between glass tubes until every tube holds a single colour. The rule is simple: a tube holds four units, a pour needs an empty tube or a tube whose top colour matches, and the whole run of that colour moves at once if it fits. This version is a complete game with 20 levels in four tiers, hidden layers, a hint solver, free undo, a Daily Puzzle with a streak and a pour animation, in plain HTML, CSS and JavaScript with no libraries, images or audio files.
Boards that are always solvable, generated backwards
A random deal can produce a board nobody can finish. Instead scramble() starts from the solved board and plays moves backwards. Each step is the exact inverse of a legal pour: take k units from the top of one tube and put them on a tube whose top colour is different (or empty). Played forwards in reverse order, those steps solve the board, so a solution is guaranteed, and the number of steps is the par. Boards that are not mixed enough, or that start already sorted, are thrown away and the next seed is tried. A seeded random generator (mulberry32) means level i is the same board for every player.
Levels as data
The LEVELS array holds, for each level, the number of colours, the number of empty tubes, how many scramble steps to apply and whether layers are hidden. The four tiers (Splash, Stream, Torrent, Flood) grow from 3 colours to 12. From level 11, only the top unit of each tube is visible and the layers underneath show a question mark until they reach the top, so you have to plan with partial information. Adding a level means adding one row.
A hint solver, not a canned answer
The Hint button runs a greedy best-first search (solve()) from the current board, with a small heuristic: how many units sit on top of a different colour, and how many tubes start with the same colour. It uses a binary heap, a canonical key that ignores the order of the tubes, and caps on the number of nodes and the time. The first move of the solution found is highlighted: the source tube in amber and the target tube in green. A hint costs one star, and each level gives three.
Pouring you can see and hear
When you pour, the source tube lifts, tilts toward the target and a stream of the right colour flows down before the units change tubes. The new layers grow into place, and the sound is a run of short bubble tones whose length matches the number of units moved. A completed tube glows green and is locked. Pours that would only waste a move, such as emptying a single-colour tube into an empty tube, are refused with a short explanation.
Stars, undo and the daily puzzle
Moves are counted against the par. Three stars for par plus about 25 percent, two stars for about 70 percent more, and one star for any solution, minus one star if you used a hint. Undo is free and removes the move from the counter, because it restores a snapshot of the tubes and the hidden layers. Winning a level unlocks the next. The Daily Puzzle builds its board from the date, so everyone plays the same one, and clearing it on consecutive days builds a streak. Progress, best moves and the streak are saved to localStorage inside try/catch.
Accessible and responsive
Every colour can show a symbol (a circle, triangle, square and so on), so the game does not depend on telling colours apart. Tubes are focusable buttons with labels such as "Tube 3: colour 2, colour 5", and the keyboard works: arrow keys move focus, Enter or Space selects and pours, the number keys pick a tube, and Z, H and R undo, hint and restart. The whole game scales to short preview areas, and on phones the layout stacks and the page scrolls.
Step by step
How to Use
- 1Pick a level or the Daily PuzzleThe menu shows 20 levels in four tiers, with your stars on each. Level 1 is open at first and each solved level unlocks the next. The gold Daily Puzzle card starts the puzzle of the day, which is the same for everyone.
- 2Select a tube and pourTap a tube to lift it, then tap another tube to pour into it. You can pour onto an empty tube or onto a tube whose top colour matches, as long as there is room. The whole top run of that colour moves at once if it fits.
- 3Sort every colourYou win when every colour fills a single tube. A finished tube glows green and locks, and the progress bar above the board shows how many colours are done.
- 4Watch for hidden layersFrom level 11 only the top unit of each tube is visible. The layers below show a question mark and are revealed when they reach the top, so plan your pours with what you can see.
- 5Use undo and hintsUndo (Z) is free and takes the move back off the counter. Hint (H) shows a good next pour, highlighting the source in amber and the target in green. You get three hints per level and each one costs a star. Restart (R) starts the level again.
- 6Earn stars, turn on symbolsFinish within about 25 percent of the par for three stars. The Symbols button shows a different shape on every colour, which helps if colours are hard to tell apart. Your stars, best moves and daily streak are saved in this browser.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
The board is not dealt at random. scramble() starts from the solved board and applies inverse pours: it takes k units from the top of a tube and puts them on a tube whose top is a different colour or empty. Each of those steps, played forwards, is a legal pour, so playing the steps in reverse order solves the board. The number of steps is the par shown in the HUD.
It would only waste a move, because the colour is already sorted and nothing changes about the puzzle. legal() refuses it and the game shows a short message. Full single-colour tubes are also locked, since taking units out of a finished tube is never useful.
solve() runs a greedy best-first search from the current board. The heuristic counts units that sit on a different colour and tubes that start with the same colour, a binary heap picks the most promising state, and a canonical key ignores the order of the tubes so equal boards are not searched twice. The first move of the path it finds is shown. Because a hint does part of the thinking, the star rating drops by one when you use it.
From level 11 each unit has a revealed flag. At the start only the top unit of every tube is revealed, and a unit is revealed as soon as it becomes the top of its tube. Units you pour keep being visible, and a finished tube reveals everything. Undo restores the flags together with the tubes.
Add a row to the LEVELS array with the number of colours (up to 12), the number of empty tubes, the scramble depth and whether layers are hidden. More scramble steps mix the board more and raise the par. The menu shows five levels per tier, so add levels in groups of five, or edit the TIERS array. Colours and their symbols are in the COLORS array.
Yes. All localStorage reads and writes are wrapped in try/catch, so a blocked storage only means that progress is not saved. The AudioContext is created when a level starts and every sound call is wrapped. Tubes respond to pointer events, and on narrow screens the layout stacks and the page scrolls.