Anchored Auto Layout
npm

Hover or focus a box to measure it. Click its tag, or press ] and [, to pin one. Esc unpins.

    Legend
    • Anchor: a box with data-⚓️-name
    • Placed by anchors: out of flow
    • Gap from the anchor's edge, in px
    • Edges of the box you're inspecting

    Every tag, line and number here is itself placed by data-⚓️-* attributes. JS only measures.

    Drag to dock: chat-head snapping with data-⚓️-side

    Drag a picture-in-picture camera bubble and release: it snaps to the nearest side of the call and swings there.

    Full page
    <main class="demo">
      <header class="intro">
        <h1>Drag to dock</h1>
        <p>
          Drag your camera bubble anywhere and let go: it snaps to the nearest side of the call.
          The script only decides <em>which</em> side and writes it to <code>data-⚓️-side</code>;
          the dock position, the lane size (<code>data-⚓️-sync-*</code>) and the swing
          (<code>data-⚓️-tween</code>) are all the library. Keyboard: focus the bubble, use the arrow keys.
        </p>
      </header>
    
      <div class="bar">
        <output class="status" id="status" aria-live="polite">Docked <b>after</b></output>
        <label class="xray-toggle"><input type="checkbox" id="xray"> X-ray</label>
      </div>
    
      <div class="stage" data-⚓️-root>
        <figure class="feed" data-⚓️-name="--feed">
          <div class="screen" aria-hidden="true">
            <span class="slide-title">Q4 layout review</span>
            <span class="bars"><i></i><i></i><i></i><i></i><i></i></span>
          </div>
          <figcaption><span class="rec"></span> Priya is presenting</figcaption>
        </figure>
    
        <!-- Drop hints: the same four lanes, one per side, anchored to the feed. -->
        <div class="zone" data-zone="above"  data-⚓️-to="--feed" data-⚓️-side="above"  data-⚓️-align-leading data-⚓️-sync-width data-⚓️-sync-height></div>
        <div class="zone" data-zone="below"  data-⚓️-to="--feed" data-⚓️-side="below"  data-⚓️-align-leading data-⚓️-sync-width data-⚓️-sync-height></div>
        <div class="zone" data-zone="before" data-⚓️-to="--feed" data-⚓️-side="before" data-⚓️-align-top     data-⚓️-sync-width data-⚓️-sync-height></div>
        <div class="zone" data-zone="after"  data-⚓️-to="--feed" data-⚓️-side="after"  data-⚓️-align-top     data-⚓️-sync-width data-⚓️-sync-height></div>
    
        <!-- The dock lane. The bubble centres itself inside it. -->
        <div
          class="lane"
          data-⚓️-to="--feed"
          data-⚓️-side="after"
          data-⚓️-align-top
          data-⚓️-sync-width
          data-⚓️-sync-height
          data-⚓️-tween
          data-⚓️-transition="morph"
        >
          <button class="pip" type="button" aria-describedby="status" aria-label="Your camera. Drag it, or press an arrow key to dock it to that side of the call.">
            <span class="face" aria-hidden="true">You</span>
            <span class="mic" aria-hidden="true"></span>
          </button>
        </div>
      </div>
    </main>

    data-⚓️-align-leadingdata-⚓️-align-topdata-⚓️-namedata-⚓️-rootdata-⚓️-sidedata-⚓️-sync-heightdata-⚓️-sync-widthdata-⚓️-todata-⚓️-transitiondata-⚓️-tween

    Copied