100vh on a phone is taller than what you can see. It's the height with the browser toolbars hidden, so a full-height hero puts its bottom edge under the address bar.
svh: toolbars showing. lvh: hidden. dvh: whatever it is right now.
z-index: 9999 and it's still underneath? An ancestor probably has opacity below 1, a transform or a filter. Each one creates a stacking context, and z-index only competes inside its own.
Raise the ancestor, not the child.
object-fit: cover is Figma's Fill. object-fit: contain is Fit.
The catch is object-position. Fill always centres the image, so a photo the site anchors to the top comes out centred. In Figma that needs Crop, not Fill.
An element with transform: scale(2) has two sizes. offsetWidth reports its layout box, untouched by the transform. getBoundingClientRect() reports what's on screen, twice as wide.
Neither is wrong. Pick the one that answers your question.
@MikkyInnovate Frames win for one specific reason: only a Frame can Hug. A Rectangle in Auto Layout can be Fixed or Fill, never Hug, because there's nothing inside it to hug. The cost: Frames clip by default, so a child's drop shadow gets cut at the edge. Turn Clip content off.
DOMContentLoaded, load, document.fonts.ready: three "ready" signals, and none of them means the page is finished.
Content a script fetches after load was never part of load's promise. If you need a finished page, wait for the DOM to stop changing.
@Wuraoladesigns Next question is the fun one: which file is the truth now? Timing, easing and the in-between states only exist in the build. Figma can't hold them.
So do you keep updating the frames, or has Figma become the sketch and the app the spec?
@iamdavidhill I'd sharpen it: AI made screens cheap, so the scarce skill is no longer making them. It's deciding which flow shouldn't exist.
Hire designers for editing, not output. That's the part a model won't volunteer.
@emilkowalski The catch is enter animations. A transition needs a "before" style, and a freshly mounted element has none, so it just pops in.
That's what Base UI's data-starting-style is for. In plain CSS, the starting-style at-rule does the same job now.
@uiux_hamad Hot take: a neat grid is still the beginner version. Tidy, but it doesn't say what comes after "Pay".
Pro files read like the product: one row per flow, screens in the order a user hits them, each row named ("Checkout").
Tidy is for you. Readable is for everyone else.
You can't trigger :hover from JavaScript. A synthetic mouseover runs your listeners, but :hover only matches under the real pointer.
To inspect hover styles on a live site: DevTools → Styles → :hov → tick :hover.
Figma plugin code runs on the main thread. One long synchronous pass, like findAll over a big file, freezes the editor and your plugin's UI with it. The spinner you added won't even spin.
Split the walk into chunks and await between them.
New in Web2Wireframe: imported layers get real names.
Heading 1, Button, Link - Sign in, Paragraph. Not div.nav-item--2fJk.
Prefer the original HTML names? One setting brings them back.
document.getAnimations() returns every active animation on the page, CSS animations and transitions included. Call finish() on each and the page jumps to its end state.
Except infinite ones: finish() on a looping animation throws InvalidStateError. Filter those out first.
Ask a subgrid for its computed grid-template-columns and the answer is the keyword subgrid. Inherited line names, no track sizes — the tracks belong to the ancestor.
A parser reading computed values gets a keyword where the geometry should be, and collapses the grid.
Read a paint back with getComputedStyle and you get the CSS spelling of it: url(), with the reference in quotes.
Write that same string into an SVG fill attribute and it dangles. A FuncIRI has no quoted form, so the gradient is dropped and the icon paints solid black.
A canvas element that has drawn one cross-origin image is tainted for life. getImageData and toDataURL throw SecurityError, and adding the CORS header later doesn't un-taint it — the taint is on the canvas, not on the request.
The pixels stay on screen. JS just can't read them.
Auto-scrolling a page to trigger lazy-loading has two traps.
A step larger than the viewport skips content: IntersectionObserver reports at the position you land on, not the ground you flew over.
And scrolling back to the top rewinds every scroll-driven animation.
Resizing the viewport after the page has loaded gives you a page that never agreed to that width.
srcset, sizes, media queries and lazy-load thresholds all resolve once, at load. Nothing re-runs them for you.
Set the viewport first. Then navigate.