dom

3 posts

figma

A Properties Panel and Annotations, Now in Figma Make | Figma Blog (opens in new tab)

Figma Make now combines visual editing with code-aware prompting through a properties panel and annotations. The properties panel handles precise visual changes, while annotations let users describe interactions and animations in context. Together, these tools reduce prompting guesswork, use fewer credits, and help ensure visual edits are reflected in the underlying code. ## Visual Editing with the Properties Panel - Users can select elements and adjust spacing, typography, layout, opacity, z-index, borders, corner radii, and other properties. - A DOM tree acts like a layers panel, making it easier to find and select elements in the code. - Multiple instances of an element can be updated simultaneously. - Edits use existing color and typography tokens from the codebase. - Each change is staged in the prompt box for review or disposal before being applied. - Applying the changes updates the underlying code and creates a new file version. - Future Code Connect integration will link Make elements to Figma Design components. ## Contextual Changes with Annotations - Users can mark one or more areas directly on the canvas and describe the desired change. - Annotations support behavior beyond basic styling, such as: - Hover zoom effects - Delayed button fades - Press effects - Full-screen navigation overlays - The agent receives the exact location and context of the selected elements, making prompts more specific. - This approach supports flexible natural-language instructions while avoiding the ambiguity of describing element locations manually. ## Credit Savings and Workflow - Direct manipulation gives the agent a precise target and requires fewer tokens than a text-only prompt. - Edits are staged without consuming credits. - Credits are used only when the user applies the changes. - The workflow keeps design experimentation, review, prompting, and code updates in one continuous process. Figma’s broader goal is to make code editing feel more like visual design. The same properties-and-annotation workflow is planned for code layers on the Figma canvas, further connecting design exploration with production code.

figma

Building Accessibility Into a Canvas-Based Product | Figma Blog (opens in new tab)

Figma’s canvas-based rendering enables performance features such as infinite zoom and real-time collaboration, but it removes the browser’s built-in accessibility support. To restore that support, Figma built a synchronized “Mirror DOM” that represents the canvas in ordinary DOM elements for screen readers and keyboard users. The system combines an internal accessibility tree, React-rendered mirror elements, bidirectional selection syncing, and announcements for non-navigational changes. ## Why Canvas Requires a Different Accessibility Strategy - Figma renders designs on a canvas rather than with traditional HTML and DOM. - This improves performance but leaves the browser’s accessibility tree nearly empty. - Unlike a conventional web app with semantic elements such as `<button>`, `<p>`, and `<img>`, Figma’s canvas effectively has only one focus-holding `<input>`. - Without additional work, screen readers cannot navigate or meaningfully interpret the layers in a Figma file. ## Synthesizing an Accessibility Tree - Browsers normally derive an accessibility tree from the DOM, semantic HTML, ARIA attributes, and computed state. - Figma created its own internal accessibility tree to provide equivalent non-visual information for each design layer. - Each layer receives an accessible summary describing the role and content a screen reader should announce. - Summaries vary according to context: - In prototypes, editing-related layers can be omitted, while text and interactive roles are preserved for viewers. - In editing mode, structures such as autolayout frames need to remain available. - The tree is flattened by removing omitted nodes and connecting their relevant descendants. - Figma builds the tree initially, then applies surgical updates as documents change instead of rebuilding everything. ## Rendering the Mirror DOM - A recursive React component converts the internal accessibility tree into DOM elements. - Each component subscribes to accessibility data for one design layer and renders its role, label, and children. - React’s incremental updates help keep DOM changes minimal as the design changes. - The resulting elements are invisible to sighted users but available to assistive technologies. ## Synchronizing Canvas and Screen Reader Interaction - Figma maintains bidirectional synchronization between the visual canvas and the Mirror DOM. - Selecting a layer on the canvas moves focus to the corresponding DOM element. - When a screen reader user navigates the Mirror DOM, Figma updates the canvas selection accordingly. - This connects non-visual navigation with the editor’s visual state. ## Announcing Changes - A separate announcement system communicates changes that are not primarily navigational. - It reports actions such as nudging objects, switching tools, and other updates that would normally be apparent visually. - Together with the Mirror DOM, these announcements help screen reader users understand both the document structure and ongoing editor activity. Figma’s approach shows that accessibility can be rebuilt for canvas applications by maintaining a semantic representation alongside the rendering layer. Applications that prioritize canvas performance should provide a synchronized accessibility model rather than relying on the canvas itself to expose meaning to assistive technologies.

github

The uphill climb of making diff lines performant (opens in new tab)

GitHub rebuilt the pull request **Files changed** experience to keep diff reviews responsive across everything from tiny fixes to massive changes. The core conclusion is that no single optimization solves performance at scale; instead, targeted rendering improvements, virtualization, and simpler components must work together. Early results show that even small reductions in DOM size can have substantial effects on memory usage and interaction latency in large pull requests. ## Performance Challenges at GitHub’s Scale - Pull requests may contain thousands of files and millions of lines. - In extreme cases, the old experience reached: - More than **1 GB of JavaScript heap usage** - Over **400,000 DOM nodes** - Unacceptably high Interaction to Next Paint (INP) scores - Large reviews became sluggish or nearly unusable, despite the experience remaining fast for most smaller pull requests. ## A Strategy Based on Pull Request Size GitHub concluded that different pull request sizes require different performance strategies: - **Optimize diff-line components** so medium and large reviews remain fast without losing expected browser behavior, such as native find-in-page. - **Use virtualization for the largest reviews**, rendering only the content currently needed to preserve responsiveness and stability. - **Improve foundational components and rendering**, allowing performance gains to benefit every pull request size. ## Problems with the Original Diff Architecture The first React implementation made each diff line unnecessarily expensive: - Unified view used roughly **10 DOM elements per line**; split view used about **15**, before syntax highlighting added more `<span>` elements. - Each unified diff line typically involved at least **eight React components**, while split view involved at least **13**. - Additional states—such as comments, hover, and focus—could add still more components. - Small components often registered five or six React event handlers each, resulting in **20 or more handlers per line**. - These costs multiplied across thousands of lines, increasing JavaScript heap usage and worsening INP. - The component-heavy design was initially reasonable when React was introduced, but proved unsustainable for unbounded data sets. ## Incremental Improvements in the New Design GitHub’s second version focused on simplification and removing unnecessary structure: - Reduced state, JavaScript, React components, and DOM elements. - Removed redundant `<code>` tags from line-number cells. - Eliminating just two nodes per line saves approximately **20,000 DOM nodes across 10,000 lines**. - The example demonstrates how seemingly minor changes compound into meaningful improvements at large scale. The practical lesson is that performant large-scale interfaces require layered optimizations: simplify every repeated element, reduce per-item overhead, and use virtualization when rendering everything at once is no longer viable.