What's included
A laptop built in CSS 3D, in two files: a stylesheet and a script. No dependencies, no build step, no external requests — you copy them into a project and it works.
The screen isn't an image: it's an ordinary block of HTML, laid in perspective on the panel. The text stays selectable, the links clickable and focusable, and the page is drawn at the scale of a 1440 px mock-up. You put your real site in it, not a screenshot.
The geometry doesn't come from an eyeballed drawing. The perspective, the camera tilt, the lid angle and the chassis dimensions were measured to the pixel on a WebGL scene, reconstructed as volumes by inverting the projection, then checked by overlaying: the largest difference is 1.90 px on a laptop 1077 wide.
Features
-
One variable for the scale —
--l3d-largeurcommands everything, perspective included. The scaling is uniform: the scene doesn't distort, from a full-screen hero down to a thumbnail. -
The lid opens as you scroll — the
data-l3d-scrollattribute makes the angle follow the component's position in the window, and the camera straightens up over the run. Without it, the lid unfolds in one go on entering the view. The script writes a single number,--l3d-progression: the run and the window are set in CSS. - You grab it and turn it — by pointer, by finger or with the arrow keys, with a bounded travel and a springy return. The grab never starts on the panel, so the screen's text stays selectable and its links clickable.
- Pointer tracking — on hover, the scene tilts gently towards the cursor. The travel is set in CSS, the script writes only two variables.
- Works without JavaScript — the laptop appears open, screen lit, at the measured angle. That's the useful default state, never a degraded one.
- Content that follows the scale — the panel is 90 em wide whatever the size of the mockup. You write your page in em just as you'd write it in px on a 1440 mock-up.
-
Reduced motion, forced contrast — the opening, the tracking and even the delays are neutralised under
prefers-reduced-motion; underforced-colors, the parts take on outlined edges.
Dropping it into a page
Two files to load, then the markup:
<link rel="stylesheet" href="laptop-3d.css">
<script src="laptop-3d.js" defer></script>
<div class="l3d">
<div class="l3d__monde">
<div class="l3d__piece l3d__sol" aria-hidden="true"></div>
<div class="l3d__piece l3d__plateau" aria-hidden="true">
<div class="l3d__clavier">…</div>
<div class="l3d__trackpad"></div>
</div>
<div class="l3d__piece l3d__tranche" aria-hidden="true">
<span class="l3d__encoche"></span>
</div>
<div class="l3d__piece l3d__capot">
<div class="l3d__dalle">
<div class="l3d__ecran">
<!-- your page, here -->
</div>
</div>
</div>
</div>
</div>
A single declaration sizes it:
.l3d { --l3d-largeur: min(760px, 88vw); }. It needs an absolute length, or a function that yields one — a bare percentage can't be divided.
What you should know
- The screen's content is written in em. The component sets the panel's text size so the panel is 90 em wide. Content written in pixels would keep its absolute size while the laptop shrinks: on a 700 px thumbnail, a 54 px heading overflows.
-
The parts stay flat. Each part is a plane, and its details are painted into it. Giving it
transform-style: preserve-3dwould sort the panel separately from the lid, and the bezel would disappear across its lower third — a trap that's expensive to diagnose. - No physical rendering of the light. The original is a 3D model lit in WebGL; here the chassis is painted with gradients measured from that rendering. The geometry is reproduced, the reflections are approximated.
-
No inline styles, no inline scripts. The component honours the site's strict security policy — checked by serving the folder over HTTP with the header, pointer tracking included — and never uses
innerHTML. - The design comes from elsewhere. The proportions follow those of a commercial Framer component, measured on its rendering. The code itself is original: nothing was taken from its implementation, and the original 3D model isn't used.
Take it, open it, break it.
This component is free. The full library — the templates and the other components — comes with the subscription, alongside the course.
Immediate access · No commitment · Cancel in one click