Mobile Camera Screen — Free HTML CSS JS UI Snippet

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

What's included

Features

Viewfinder frame
Gradient feed with a radial subject highlight.
CSS focus reticle
Corner brackets from one element's pseudo-elements.
Full-screen flash
Keyframe overlay fires on every shutter press.
Animation restart
Reflow trick re-fires the flash and pop.
Cycling thumbnails
Captures pop a new image into the corner.
Rule-of-thirds grid
Toggleable thirds overlay.
Mode selector
Photo, Portrait, Square, Video with active label.
No dependency
Pure HTML, CSS, and vanilla JavaScript.

About this UI Snippet

Mobile Camera Screen — Viewfinder & Shutter UI

Screenshot of the Mobile Camera Screen snippet rendered live

A camera screen is almost all overlay — a viewfinder filling the frame, a row of quick toggles on top, a mode selector and shutter at the bottom, and a thumbnail of your last shot. This snippet builds a complete, interactive one inside a CSS phone frame: pressing the shutter fires a white flash and drops a new photo into the thumbnail, the grid and flash toggles work, and the flip button spins — in HTML, CSS, and vanilla JavaScript with no camera access required.

The viewfinder and focus frame

The viewfinder is a gradient stand-in for a live feed with a soft radial highlight suggesting a subject. Over it sits a focus frame with two accent corner brackets built from a single element's ::before and ::after — each is a small box with only two borders and one rounded corner, the universal "autofocus reticle" look. A rule-of-thirds grid overlay can be toggled on and off.

A shutter that fires a flash

Tapping the shutter plays a full-screen white flash via a @keyframes animation on an absolutely positioned overlay. To make it fire on every press — not just the first — the code removes the animation class, forces a reflow with void flash.offsetWidth, and re-adds it, the standard CSS-animation-restart trick. The shutter's inner disc also scales down on :active for a physical press feel.

Captured thumbnails that cycle

Each capture drops the next gradient from a small array into the thumbnail and replays a pop animation so the shot appears to fly into the corner, exactly how phone cameras animate a taken photo shrinking into the gallery button. The array cycles with a modulo so you can keep shooting.

Working toggles

The flash and grid buttons flip an amber "on" state; turning grid on reveals the thirds overlay. The mode selector — Video, Photo, Portrait, Square — moves an amber active label, and the flip-camera button rotates a full turn on tap to signal switching between front and rear cameras. Each is a small, self-contained interaction that mirrors a real camera app.

Accessibility and performance

Every control — the top toggles, the mode buttons, the shutter, and flip — is a real <button> with an aria-label, so the camera UI is fully keyboard-operable and screen readers announce each action rather than a bare glyph. When you adapt it, reflect toggle state with aria-pressed on the flash and grid buttons and mark the active mode with aria-pressed too, so their on state is announced and not carried by color alone. One accessibility consideration for the flash: the full-screen white pulse can be jarring, so gate it behind a prefers-reduced-motion check for users who opt out of motion. Performance is deliberately cheap: the flash and thumbnail pop are single CSS keyframes restarted with a forced reflow rather than by creating nodes, the viewfinder and focus reticle are pure CSS with no repaint cost while idle, and the grid overlay is one gradient toggled with the hidden attribute. Wiring a real camera adds a <video> element and a canvas capture, but the overlay chrome stays exactly as lightweight as it is here.

Reusing it

Replace the gradient viewfinder with a <video> element bound to getUserMedia, capture real frames to a canvas on shutter, and wire the modes to your capture settings. Lift the overlay out of the phone frame for a responsive web camera, or keep it framed beside a camera UI control panel to present a full capture flow.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't need to reverse-engineer the flash retrigger from memory to be confident in it. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why the shutter handler removes the fire class, reads flash.offsetWidth, and only then re-adds the class to force the flash keyframe to replay on every single press, or how the focus-frame's corner brackets are built from just one element's before and after pseudo-elements with partial borders. The same assistant is useful for optimizing it — asking whether the same forced-reflow pattern used for the flash and the thumbnail pop could be consolidated into one small reusable helper function, or whether the gradient viewfinder background could be replaced by a real getUserMedia video feed without touching the overlay chrome. It's just as useful for extending the screen: ask it to wire the shutter to actually capture a video frame to a canvas, add a pinch-to-zoom gesture on the viewfinder, or make the flip-camera button actually swap between two video streams. 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 capture screen" inside a CSS phone frame, in plain HTML, CSS, and vanilla JavaScript — no real camera access required, no libraries.

Requirements:
- A phone-shaped outer frame containing a dark screen with a fake status bar, a row of top toggle icon buttons (flash, timer, grid, settings), a large viewfinder area, a row of capture-mode labels (e.g. Video, Photo, Portrait, Square), and a bottom control row with a thumbnail preview, a circular shutter button, and a flip-camera button.
- The viewfinder must be a gradient background standing in for a live feed (no actual video element required), with a focus-frame overlay: a bordered rounded rectangle whose two accent corner brackets are built from a single element's ::before and ::after pseudo-elements, each showing only two of its four borders and one rounded corner, so together they read as an autofocus reticle.
- A toggleable rule-of-thirds grid overlay: a hidden layer with two repeating linear-gradients (one horizontal, one vertical) forming a 3x3 grid, shown or hidden via a button that also toggles its own "on" visual state.
- Pressing the shutter must trigger a full-screen white flash: an absolutely positioned overlay with a CSS keyframe animation that fades in then out. Because a CSS animation only plays once per class application, the code must remove the animation-triggering class, force a synchronous reflow by reading the element's offsetWidth, and then re-add the class — so the flash fires freshly on every single shutter press, not just the first.
- Each shutter press must also cycle through a small fixed array of gradient "photos," dropping the next one into a small thumbnail element in the corner, and replaying a pop-in scale animation on that thumbnail using the same remove-reflow-reapply technique.
- Flash and grid buttons should toggle an "on" visual state (e.g. amber highlight) on click. The mode-selector labels should move an "active" highlight between them on click. A flip-camera button should visually rotate a full 360 degrees on each click to suggest switching between front and rear cameras.
- Every control must be a real button with an aria-label, so the camera UI is fully operable via keyboard and announced correctly by screen readers.

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="mcm-phone">
  <div class="mcm-screen" id="mcmScreen">
    <div class="mcm-flash" id="mcmFlash"></div>
    <div class="mcm-status"><span>9:41</span><span class="mcm-batt"><i></i></span></div>

    <div class="mcm-top">
      <button class="mcm-tbtn" id="mcmFlashBtn" aria-label="Flash">&#9889;</button>
      <button class="mcm-tbtn" aria-label="Timer">&#9203;</button>
      <button class="mcm-tbtn" id="mcmGridBtn" aria-label="Grid">&#9638;</button>
      <button class="mcm-tbtn" aria-label="Settings">&#9881;</button>
    </div>

    <div class="mcm-view">
      <div class="mcm-grid" id="mcmGrid" hidden></div>
      <div class="mcm-frame"></div>
    </div>

    <div class="mcm-modes" id="mcmModes">
      <button class="mcm-mode">VIDEO</button>
      <button class="mcm-mode active">PHOTO</button>
      <button class="mcm-mode">PORTRAIT</button>
      <button class="mcm-mode">SQUARE</button>
    </div>

    <div class="mcm-bottom">
      <div class="mcm-thumb" id="mcmThumb"></div>
      <button class="mcm-shutter" id="mcmShutter" aria-label="Capture"><span></span></button>
      <button class="mcm-flip" id="mcmFlip" aria-label="Flip camera">&#8635;</button>
    </div>
  </div>
</div>

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA camera UI renders with a viewfinder, focus frame, mode selector, and shutter.
  2. 2
    Press the shutterA white flash fires across the screen and a new photo pops into the thumbnail corner.
  3. 3
    Keep shootingEach press cycles a different captured image into the thumbnail.
  4. 4
    Toggle the gridThe grid button reveals a rule-of-thirds overlay on the viewfinder.
  5. 5
    Toggle flashThe flash button flips to an amber on state.
  6. 6
    Switch modes and flipPick Photo, Portrait, or Square, and tap flip to spin the camera-switch button.

Real-world uses

Common Use Cases

Camera apps
The capture screen beside a camera UI panel.
Photo tools
Feed shots into a photo gallery.
Scanner UIs
Reuse the frame for a slider captcha style scanner.
Story creation
App mockups
Present it inside a phone mockup.
Learning overlays
A reference for viewfinder overlays and flash effects.
Related: Mobile Alarm Clock Screen
See the Mobile Alarm Clock Screen for a related mobile pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

No — the viewfinder is a gradient stand-in and the shutter fires a flash and cycles demo images. To use a real camera, bind a video element to getUserMedia, and on shutter draw the current video frame to a canvas and use that as the captured image. The flash, grid, and mode UI stay exactly the same.

The flash is a full-screen overlay with a keyframe animation triggered by a class. Since CSS animations only run on first application, the code removes the class, reads flash.offsetWidth to force a reflow, then re-adds it. That reflow lets the browser treat the animation as new, so it fires on every capture rather than only once.

The frame is a bordered rounded rectangle, and its two amber corner brackets are the ::before and ::after pseudo-elements of a single element. Each bracket is a small box showing only two of its borders with one rounded corner, which produces the L-shaped autofocus reticle look purely in CSS.

On capture the thumbnail gets the next image and replays a pop keyframe that scales it up from small, imitating a just-taken photo flying into the gallery button. The images come from a small array cycled with a modulo, so repeated shots keep swapping the thumbnail.

Hold the active mode, flash-on, grid-on, and last capture in state and bind classes to them rather than toggling classList. Replace the gradient viewfinder with a video ref bound to getUserMedia, and capture frames to a canvas on shutter. Re-fire the flash with a state-driven key change. Tailwind expresses the overlays and controls with utilities.