This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art.

Inspiration

Tonkotsu ramen. It's the bowl I want when nothing else will do — slow-simmered pork-bone broth turned milky and opaque, a jammy marinated egg, soft rolled chashu, scallions, menma, a clean nori sheet, and that iconic pink narutomaki spiral. The whole thing is comfort in liquid form: rich, warm, and steaming.

I wanted to see if that feeling — not just the look of food, but the mood of a quiet late-night ramen-ya — could come through with CSS as the main ingredient. So this isn't just a bowl on a page; it's a composed table scene: warm wooden grain under an overhead light, a bamboo trivet, chopsticks resting on a ceramic hashioki, a small dish of pickled ginger, and a stamped order ticket.

Demo

I built it as a single self-contained HTML file (HTML + CSS + a light sprinkle of JavaScript). It's live here:

Try it: hover the ajitama egg, and move your cursor around — the steam and the overhead light shift with a gentle parallax. (Everything still works and stays still if you prefer reduced motion.)

Journey

The star of the show is CSS, as the prompt asks. JavaScript is deliberately light — only two small, purposeful things: nudging the steam's rhythm so it never loops like a metronome, and a soft pointer-parallax for depth. Here's what the CSS is doing:

  • Broth — layered radial-gradients for the milky tonkotsu surface, with floating chili-oil droplets and sesame specks stacked via tiny radial-gradients in mix-blend-mode: screen.
  • Narutomaki swirl — the pink spiral is a conic-gradient cut into rings with a radial-gradient mask, so you get the real "pinwheel" cross-section instead of a flat disc.
  • Chashu — rolled pork viewed from above: a repeating-radial-gradient renders the concentric spiral of the meat roll, with faint fat layers and a glaze highlight.
  • Noodlesrepeating-radial-gradient tangles peeking out from under the toppings.
  • Ceramic bowl — the depth is all box-shadow: inset lights on the rim, inset darkness inside, and a cast shadow below, plus a curved specular highlight on the flank.
  • Steam — blurred, semi-transparent puffs rising on @keyframes with randomized durations and three drift variants (rise, riseL, riseR) so the plume feels organic rather than mechanical.
  • Typography & mood — a Noto Serif JP + Cormorant Garamond title block (ラーメン / Tonkotsu Ramen), a torn-edge order ticket with a red 味 hanko stamp, and a warm color grade to push the "I want to eat this" psychology.

A real bug worth calling out: at one point the wood-grain background was rendering on top of the bowl, burning dark stripes across the broth, chopsticks, and ticket. The culprit was a mix-blend-mode: multiply ::after layer painting above the scene. The fix was giving the scene z-index + isolation: isolate so all the internal blend modes stay contained — a good reminder that stacking context, not just z-index, decides what wins.

What I'm proud of: the narutomaki mask trick and the steam randomization — both are small but they sell the "alive" feeling.

What's next: a pour-and-stir animation on click, and a dark/light "shop sign" toggle.

This work is licensed under the MIT License.