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.

    Corner toasts that pick a side

    Toasts that stack below top-corner anchors and above bottom-corner anchors.

    Full page
    <header class="intro">
      <h1>Corner toasts</h1>
      <p>
        Pick a corner and fire some toasts. Each corner anchor carries its own
        <code>data-⚓️-side</code> (top corners stack <em>below</em>, bottom corners stack <em>above</em>)
        and cross-axis <code>data-⚓️-align-*</code>. Toasts chain: the newest anchors to the corner, every
        older one anchors to the toast in front of it. Switch corners and the whole stack
        tweens across the screen (<code>data-⚓️-tween</code> + <code>morph</code>). JS only re-links anchor names.
      </p>
    </header>
    
    <div class="controls">
      <fieldset class="corners" aria-label="Toast corner">
        <label><input type="radio" name="corner" value="--tl"><span>↖</span></label>
        <label><input type="radio" name="corner" value="--tr"><span>↗</span></label>
        <label><input type="radio" name="corner" value="--bl"><span>↙</span></label>
        <label><input type="radio" name="corner" value="--br" checked><span>↘</span></label>
      </fieldset>
      <button class="primary" id="toast">Toast</button>
      <button class="secondary" id="burst">Burst ×3</button>
      <label class="xray-toggle"><input type="checkbox" id="xray"> X-ray</label>
    </div>
    
    <div class="screen" data-⚓️-root>
      <div class="wallpaper" aria-hidden="true"></div>
    
      <!-- Corner anchors. Where they live decides which way toasts stack. -->
      <button class="corner" aria-label="Top left" data-⚓️-name="--tl" data-⚓️-pin-top data-⚓️-pin-leading
        data-toast-side="below" data-toast-align="leading"></button>
      <button class="corner" aria-label="Top right" data-⚓️-name="--tr" data-⚓️-pin-top data-⚓️-pin-trailing
        data-toast-side="below" data-toast-align="trailing"></button>
      <button class="corner" aria-label="Bottom left" data-⚓️-name="--bl" data-⚓️-pin-bottom data-⚓️-pin-leading
        data-toast-side="above" data-toast-align="leading"></button>
      <button class="corner" aria-label="Bottom right" data-⚓️-name="--br" data-⚓️-pin-bottom data-⚓️-pin-trailing
        data-toast-side="above" data-toast-align="trailing"></button>
    
      <!-- Newest toast first in DOM: an anchor must precede whatever anchors to it. -->
      <div class="toasts" id="toasts" role="status" aria-live="polite"></div>
    </div>
    
    <template id="toast-tpl">
      <div class="toast" data-⚓️-tween data-⚓️-transition="morph">
        <div class="card">
          <span class="icon" aria-hidden="true"></span>
          <div class="text"><strong></strong><span></span></div>
          <button class="close" aria-label="Dismiss">×</button>
          <i class="timer" aria-hidden="true"></i>
        </div>
      </div>
    </template>

    data-⚓️-namedata-⚓️-pin-bottomdata-⚓️-pin-leadingdata-⚓️-pin-topdata-⚓️-pin-trailingdata-⚓️-rootdata-⚓️-sidedata-⚓️-transitiondata-⚓️-tween

    Copied