Happy Onigiri
A smiling rice ball drawn with two divs and one very hardworking CSS property.
← you, in 25 minutes.
what you'll build
Here's the plan
A smiling onigiri (rice ball) resting on a tiny picnic scene: paper backdrop, coral-and-cream cloth, and a little bento-box silhouette. No images, no SVG, no libraries — just HTML and CSS you can paste anywhere.
You’ll learn
- How border-radius can sculpt almost any soft shape (the four-corner and eight-value tricks)
- Positioning face parts with position: absolute + percentages, so the face scales with the body
- Making anything look alive with a 3-line keyframe animation
- Skill level
- Beginner
- Time
- ~25 min
- Tools
- Just a browser
- Code type
- HTML + CSS
- Lines
- ~144
the steps
Build it, one change at a time
Lay out the ingredients
Start with a scene wrapper: the picnic cloth and tiny bento sit behind the snack, then the onigiri keeps its rice and nori divs inside. The face will come later, from elements inside the rice. CSS art is mostly CSS, who knew.
<div class="scene"> <div class="picnic-cloth"> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> <div class="check coral"></div> <div class="check cream"></div> </div> <div class="bento"> <div class="bento-lid"></div> </div> <div class="onigiri"> <div class="rice"> <div class="eye eye-left"></div> <div class="eye eye-right"></div> <div class="mouth"></div> <div class="blush blush-left"></div> <div class="blush blush-right"></div> </div> <div class="nori"></div> </div> </div> .scene { position: relative; width: 260px; height: 220px; overflow: hidden; background: #FBF2E5; border-radius: 18px; } .scene > .onigiri { position: absolute; left: 10px; bottom: 12px; /* scooch left and shrink a touch so the bento gets its corner */ transform: scale(0.85); transform-origin: bottom left; } .picnic-cloth { position: absolute; left: 0; right: 0; bottom: 0; height: 66px; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(3, 1fr); } .check { width: 100%; height: 100%; } .coral { background: #FF6B5E; } .cream { background: #FFFDF7; } .bento { position: absolute; right: 18px; bottom: 24px; width: 54px; height: 30px; background: #FFFDF7; border: 4px solid #2B3A55; border-radius: 10px; } .bento-lid { position: absolute; left: 7px; right: 7px; top: 9px; height: 4px; background: #2B3A55; border-radius: 4px; } .onigiri { position: relative; /* everything inside positions against this */ width: 220px; height: 200px; }picnic cloth down, tiny bento parked, rice ball still just a plan.
Shape the rice
Here's the star of the show. A plain box becomes a squishy triangle-ish rice ball with one property — border-radius in its fancy eight-value form. The four values before the / round the corners horizontally; the four after round them vertically. Big top values = soft dome. Small bottom values = gently flattened base, like it's sitting politely on the cloth.
.rice { position: absolute; inset: 0; background: #FFFDF7; border: 6px solid #2B3A55; border-radius: 50% 50% 46% 46% / 76% 76% 30% 30%; }a plump rounded triangle sitting on a picnic cloth. It already looks edible.
Wrap the nori
The nori is just a rounded rectangle hugging the bottom. We center it with the left: 50% + translateX(-50%) trick — the classic "center an absolute child" move you'll use in every doodle from now on.
.nori { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 96px; height: 62px; background: #2B3A55; border-radius: 10px 10px 16px 16px; }it's officially a picnic onigiri. A faceless, slightly unsettling picnic onigiri.
Give it a face
Faces are where doodles get a soul, and they're cheap: two dot eyes and a half-circle mouth. The half circle is another border-radius trick — round only the bottom two corners of a short wide box.
.eye { position: absolute; top: 47%; width: 15px; height: 15px; background: #2B3A55; border-radius: 50%; } .eye-left { left: 27%; } .eye-right { right: 27%; } .mouth { position: absolute; top: 54%; left: 50%; transform: translateX(-50%); width: 26px; height: 13px; background: #2B3A55; border-radius: 0 0 26px 26px; /* only the bottom corners — instant smile */ }it's smiling at you from the picnic cloth. You did that.
Blush and bob
Blush marks are the cheapest charm in CSS art: two soft pink ellipses. And a three-line keyframe makes the whole onigiri bob like it's listening to music while the picnic scene stays still.
.blush { position: absolute; top: 56%; width: 22px; height: 11px; background: #FFB3AD; border-radius: 50%; } .blush-left { left: 13%; } .blush-right { right: 13%; } .onigiri { animation: bob 2.4s ease-in-out infinite; } @keyframes bob { 0%, 100% { transform: translateY(0) rotate(-1deg); } 50% { transform: translateY(-7px) rotate(1.5deg); } }the finished, bobbing, blushing picnic onigiri.
the complete code
Everything, in one place
Skipped straight to the end? Welcome. Copy the whole thing, download it, or open it in the Playground to start remixing.
<div class="scene">
<div class="picnic-cloth">
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
<div class="check coral"></div>
<div class="check cream"></div>
</div>
<div class="bento">
<div class="bento-lid"></div>
</div>
<div class="onigiri">
<div class="rice">
<div class="eye eye-left"></div>
<div class="eye eye-right"></div>
<div class="mouth"></div>
<div class="blush blush-left"></div>
<div class="blush blush-right"></div>
</div>
<div class="nori"></div>
</div>
</div>
tips & gotchas
Mistakes we actually made
If a face part flies off into the corner of the page, its parent is missing position: relative. This catches absolutely everyone. Twice.
The eight-value border-radius is easier with a visual tool — or just wiggle the numbers in the Playground and watch the shape squish.
Percentages for face positions (not pixels) mean you can resize .onigiri and the face comes along for free.
make it yours
Remix it
- New paletteeasy
Sesame-speckled rice? Pink sakura rice? It's two background values.
- Mood swingeasy
Flip the mouth's border-radius to 26px 26px 0 0 for a deeply concerned onigiri.
- Blinkmedium
Animate the eyes' height to 2px for 0.1s every few seconds.
- A friendmedium
Duplicate, shrink, and tilt a second onigiri leaning on the first.
challenge extension
Same technique, new snack: draw a strawberry daifuku — one big soft circle, a bite-mark using a paper-colored pseudo-element, and the same face.
keep sketching
More tutorials to try
Pick another small recipe and borrow one technique for your next doodle.
- Banana BaristaSVG + CSS · doodle + food · animation tutorial
- Blueberry MilkSVG + CSS · doodle + drink · animation tutorial
- Bubble Tea BuddySVG + CSS · food + drink · animation tutorial
- Corn Soft ServeSVG + CSS · doodle + food · animation tutorial
- CSS Food MascotCSS · food + animation · animation tutorial