Camera UI — Free Phone Camera Viewfinder Snippet

Camera UI · Mobile · Plain HTML, CSS & JS · Live preview

What's included

Features

Tap-to-focus
A focus square animates where you tap.
Capture flash
A white overlay peaks and fades on the shutter.
Rule-of-thirds grid
A composition grid from layered gradients.
Mode selector
Scrollable Photo/Video/Portrait strip.
Flip animation
The camera-switch button rotates 180°.
Tactile shutter
The inner disc scales on press.
Control-aware taps
Taps on top controls don't set focus.
No dependency
Pure HTML/CSS/JS, ready for getUserMedia.

About this UI Snippet

Camera UI — Mobile Viewfinder with Tap-to-Focus

Screenshot of the Camera UI snippet rendered live

A camera UI is the viewfinder interface of a phone camera app — a live preview with a framing grid, top controls for flash and HDR, a mode selector, and the shutter, gallery, and flip-camera buttons. This snippet recreates a faithful one inside a CSS phone frame, with tap-to-focus, a capture flash, mode switching, and a camera-flip animation, in HTML, CSS, and vanilla JavaScript with no dependency.

Tap-to-focus anywhere

Tapping the viewfinder reads the pointer position relative to the preview and drops a yellow focus square there, animated with a cmFocus keyframe that overshoots then settles and fades — exactly the focus-lock affordance every camera app uses. The square is repositioned via left/top and the animation is restarted with the void offsetWidth reflow trick so it fires on every tap. Taps on the top controls are ignored so you don't focus when toggling flash.

The capture flash

Pressing the shutter fires a full-screen white overlay that quickly peaks and fades (cmFx keyframe), mimicking the brief flash of taking a photo, while the shutter button's inner disc scales down on press for tactile feedback. It's a convincing capture moment built from a single animated overlay.

The rule-of-thirds grid

The framing grid is drawn with two layered linear-gradient backgrounds sized at 33.33% — thin lines at each third — over the preview, the composition guide real cameras overlay. No SVG or extra elements; it's one element with a gradient.

Mode selector and flip

The mode strip (Photo, Video, Portrait, Pano, Time-lapse) is a horizontally-scrollable row where tapping moves a yellow .on highlight, the standard camera mode picker. The flip-camera button rotates 180° on tap via a CSS transition, suggesting the front/back switch. All interactions are class toggles routed through small handlers.

Reusing it

Replace the gradient preview with a real <video> element streaming getUserMedia, and the UI becomes a working camera. Wire the shutter to a canvas capture, the modes to real capture settings, and the flip to switching video tracks. Or keep it as a presentational mockup inside a phone mockup for app shots.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to work out the reflow-restart trick or the rule-of-thirds gradient by hand to see how this mockup is assembled. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why void focus.offsetWidth is required before re-adding the show class on every single tap, and how the framing grid achieves nine even cells from just two layered linear-gradient backgrounds sized at 33.33 percent rather than nine separate divs. The same assistant can help optimize it — asking whether the pointerdown handler's closest check against the top control bar is the cleanest way to prevent accidental focus-square drops, or whether the flash toggle's textContent update (which currently sets the same emoji either way) should actually change icons between states. It's also useful for extending the UI: ask it to wire in a real getUserMedia video stream behind the same controls, add pinch-to-zoom, or implement a working timer/self-timer countdown before capture. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a mobile "camera viewfinder UI" in plain HTML, CSS, and JavaScript inside a phone-frame mockup, with tap-to-focus and a capture flash — no libraries, and structure it so a real getUserMedia video feed could later replace the placeholder preview with no markup changes.

Requirements:
- A phone-frame container clipping a viewfinder area that displays a rule-of-thirds composition grid built from exactly one element using two layered linear-gradient backgrounds sized to create evenly spaced thin lines at each third, both horizontally and vertically — not nine separate divs and not an SVG.
- Tapping anywhere in the viewfinder (but explicitly excluding taps that land on the top control bar) must read the tap's position relative to the viewfinder's bounding rectangle and move a focus-indicator square to exactly that point, then play a keyframe animation where the square starts slightly larger and fully opaque, settles to its resting size, and fades to fully transparent — and this animation must reliably restart on every single tap even if the previous animation hasn't finished, which requires forcing a synchronous reflow between removing and re-adding the animation-triggering class.
- Pressing a shutter button must trigger a brief full-screen white flash overlay that quickly rises in opacity and fades back out, simulating a photo capture, and the shutter button's inner circle must visibly scale down while being pressed for tactile feedback.
- A horizontally scrollable row of capture mode labels (e.g. Photo, Video, Portrait) where tapping any label moves a single active-highlight class to that label and removes it from all others.
- A flash toggle button and a flip-camera button, where toggling flash adds/removes an "on" visual state and toggling flip rotates the button's icon 180 degrees via a CSS transition — both implemented as simple class toggles that could later be wired to actual camera constraints.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="cm-phone">
  <div class="cm-screen" id="cmScreen">
    <div class="cm-view" id="cmView">
      <div class="cm-grid"></div>
      <div class="cm-top">
        <button class="cm-flash" id="cmFlash"><span id="cmFlashIc">⚡</span></button>
        <span class="cm-timer">0:00</span>
        <button class="cm-hdr">HDR</button>
      </div>
      <div class="cm-focus" id="cmFocus"></div>
      <div class="cm-flashfx" id="cmFx"></div>
    </div>
    <div class="cm-controls">
      <div class="cm-modes" id="cmModes">
        <span>TIME-LAPSE</span><span>VIDEO</span><span class="on">PHOTO</span><span>PORTRAIT</span><span>PANO</span>
      </div>
      <div class="cm-bar">
        <div class="cm-thumb"></div>
        <button class="cm-shutter" id="cmShutter" aria-label="Take photo"><span></span></button>
        <button class="cm-flip" id="cmFlip" aria-label="Switch camera">
          <svg viewBox="0 0 24 24" width="22" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 7h3l1.5-2h7L17 7h3v12H4z"/><path d="M9 13a3 3 0 0 1 6 0M15 13l1.5-1.5M15 13l-1.5-1.5"/></svg>
        </button>
      </div>
    </div>
  </div>
</div>

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA camera viewfinder renders inside a phone frame.
  2. 2
    Tap the previewA focus square drops where you tap and settles.
  3. 3
    Press the shutterA white flash fires like taking a photo.
  4. 4
    Switch modesTap Photo, Video, or Portrait to move the highlight.
  5. 5
    Toggle flash and flipFlash highlights and the flip button rotates.
  6. 6
    Make it liveSwap the preview for a getUserMedia video stream.

Real-world uses

Common Use Cases

Camera app concepts
Mock a viewfinder inside a phone mockup.
Photo and video tools
Pair with an image filter editor.
Scanner and capture UIs
Reuse the frame for a QR code generator scanner.
AR and effects apps
Overlay controls beside a drawing canvas.
Marketing shots
Frame a camera app in a bento grid.
Learning live camera
A reference UI to wrap a getUserMedia stream.
Related: Alphabet Jump Index — Contacts-Style A–Z Scroll Navigation
See the Alphabet Jump Index — Contacts-Style A–Z Scroll Navigation for a related mobile pattern worth pairing with this one.
Related: Control Center Panel
See the Control Center Panel for a related mobile pattern worth pairing with this one.
Related: Swipe-to-Reveal List Item Actions (Archive / Delete)
See the Swipe-to-Reveal List Item Actions (Archive / Delete) for a related mobile pattern worth pairing with this one.
Related: Mobile Empty Cart Screen
See the Mobile Empty Cart Screen for a related mobile pattern worth pairing with this one.
Related: Mobile Medication Reminder Screen
See the Mobile Medication Reminder Screen for a related mobile pattern worth pairing with this one.
Related: Mobile Settings Screen with Live Search
See the Mobile Settings Screen with Live Search for a related mobile pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A pointerdown on the viewfinder reads the tap position relative to the preview's bounding rect and sets the focus square's left and top to that point. The square plays a keyframe that overshoots, settles, and fades, restarted each time with the void offsetWidth reflow trick. Taps on the top control bar are ignored so toggling flash doesn't drop a focus square.

The shutter click fires a full-screen white overlay whose keyframe quickly rises to near-full opacity and fades back to zero, imitating a camera flash. The shutter button's inner disc also scales down on press for feedback. It's a single animated element, so there's no heavy effect or library involved.

It's one element with two layered linear-gradient backgrounds sized at 33.33%, producing thin lines at each third both horizontally and vertically — the rule-of-thirds composition guide. Using gradients means no SVG and no extra DOM, and you can change the line opacity or spacing with a couple of values.

Yes. Replace the gradient preview with a <video> element playing a getUserMedia stream, and the UI becomes functional. Wire the shutter to draw the current frame to a canvas, the modes to capture settings, and the flip button to switch between front and back video tracks. The controls are already in place.

Render the controls and modes from state, with the active mode and flash as flags. Handle tap-to-focus by setting focus coordinates in state and animating via a key change. For a real camera, attach a getUserMedia stream to a video ref in a mount effect. Tailwind styles the grid (arbitrary gradient utilities), shutter, and mode strip.