The CSS anchor positioning specification defines anchor positioning, “where a positioned element can size and position itself relative to one or more ‘anchor elements’ elsewhere on the page.” This CSS Anchor Positioning Polyfill supports and is based on this specification.
        The proposed anchor() and
        anchor-size() functions add flexibility to how absolutely
        positioned elements can be placed within a layout. Instead of being
        sized and positioned based solely on the position of their containing
        block, the proposed new functions allow absolutely positioned elements
        to be placed relative to one or more author-defined anchor elements.
      
Note: We strive to keep the polyfill up-to-date with ongoing changes to the spec, and we welcome code contributions and financial support to make that happen.
anchor() [stylesheet]
      With polyfill applied: Target and Anchor’s right edges line up. Target’s top edge lines up with the bottom edge of the Anchor.
#my-anchor-positioning {
  anchor-name: --my-anchor-positioning;
}
#my-target-positioning {
  position: absolute;
  top: anchor(--my-anchor-positioning bottom);
  right: anchor(--my-anchor-positioning right, 50px);
}anchor() [<style> tag]
      With polyfill applied: Target is positioned at the top left corner of the Anchor.
/* a <style> tag */
#my-anchor-style-tag {
  anchor-name: --my-anchor-style-tag;
}
#my-target-style-tag {
  position: absolute;
  bottom: anchor(--my-anchor-style-tag start);
  right: anchor(--my-anchor-style-tag left);
}anchor() [inline styles]
      With polyfill applied: Target and Anchor’s right edges line up. Target’s top edge lines up with the bottom edge of the Anchor.
/* inline <style> attributes */
/* anchor */
  style="anchor-name: --my-anchor-in-line"
/* target */
  style="
    position: absolute;
    top: anchor(--my-anchor-in-line bottom);
    right: anchor(--my-anchor-in-line right);
  "anchor() [
        position-anchor property]
      With polyfill applied: Targets are positioned at the top right corner of their respective Anchors.
<div id="my-position-anchor-a" class="anchor">Anchor A</div> <div id="my-position-target-a" class="target">Target A</div> <div id="my-position-anchor-b" class="anchor">Anchor B</div> <div id="my-position-target-b" class="target">Target B</div>#my-position-target-a { position-anchor: --my-position-anchor-a; } #my-position-target-b { position-anchor: --my-position-anchor-b; } .target { position: absolute; bottom: anchor(top); left: anchor(right); } #my-position-anchor-a { anchor-name: --my-position-anchor-a; } #my-position-anchor-b { anchor-name: --my-position-anchor-b; }
popover
      With polyfill applied: Target is positioned at the bottom right corner of the Anchor.
#my-anchor-popover {
  position: absolute;
  left: 200px;
  anchor-name: --my-anchor-popover;
}
#my-target-popover {
  position: absolute;
  left: anchor(--my-anchor-popover right);
  top: anchor(--my-anchor-popover bottom);
}anchor() [anchor name set as CSS custom
        property]
      With polyfill applied: Target is positioned at the top left corner of the Anchor.
#my-anchor-name-prop {
  anchor-name: --my-anchor-name-prop;
}
#my-target-name-prop {
  --anchor-var: --my-anchor-name-prop;
  position: absolute;
  right: anchor(var(--anchor-var) left);
  bottom: anchor(var(--anchor-var) top);
}inside and outside values
      With polyfill applied: Target’s bottom edge is aligned with Anchor’s bottom edge, and Target’s left edge is aligned with Anchor’s right edge.
#inside-outside .anchor {
  anchor-name: --inside-outside;
}
#inside-outside .target {
  position: absolute;
  position-anchor: --inside-outside;
  left: anchor(outside);
  bottom: anchor(inside);
}position-try-fallbacks
      With polyfill applied, the following positions are attempted in order:
flip-block, flipping across the inline axis, and
            align the top, left edge of the target with the bottom, right edge
            of its anchor.
          flip-inline, flipping across the block axis, and
            align the bottom, right edge of the target with the top, left edge
            of its anchor.
          flip-start, flipping across a diagonal line from
            upper left to lower right, and align the top, right edge of the
            target with the bottom, left edge of its anchor.
          
          Note: Early Chromium implementations used
          position-try-options instead of
          position-try-fallbacks. We recommend adding both
          properties, or using the position-try shorthand.
        
#my-anchor-try-tactics {
  anchor-name: --my-anchor-try-tactics;
}
#my-anchor-try-tactics-2 {
  anchor-name: --my-anchor-try-tactics-2;
}
#my-target-try-tactics {
  position-anchor: --my-anchor-try-tactics;
}
#my-target-try-tactics-2 {
  position-anchor: --my-anchor-try-tactics-2;
}
#my-target-try-tactics,
#my-target-try-tactics-2 {
  position: absolute;
  bottom: anchor(top);
  left: anchor(right);
  position-try-fallbacks: flip-block, flip-inline, flip-start;
}position-try-fallbacks and
        @position-try
      With polyfill applied, the following positions are attempted in order:
#my-anchor-fallback {
  anchor-name: --my-anchor-fallback;
}
#my-anchor-fallback-2 {
  anchor-name: --my-anchor-fallback-2;
}
#my-target-fallback {
  position-anchor: --my-anchor-fallback;
}
#my-target-fallback-2 {
  position-anchor: --my-anchor-fallback-2;
}
#my-target-fallback,
#my-target-fallback-2 {
  position: absolute;
  /* First try to align the bottom, left edge of the target
     with the top, left edge of the anchor. */
  bottom: anchor(top);
  left: anchor(left);
  width: anchor-size(width);
  position-try-fallbacks: --bottom-left, --top-right, --bottom-right;
}
@position-try --bottom-left {
  /* Next try to align the top, left edge of the target
     with the bottom, left edge of the anchor. */
  top: anchor(bottom);
  left: anchor(left);
  /* Values set by the initial styles will still be applied
     unless they are explicitly reverted. */
  bottom: revert;
}
@position-try --top-right {
  /* Next try to align the bottom, right edge of the target
     with the top, right edge of the anchor. */
  bottom: anchor(top);
  right: anchor(right);
  left: revert;
  width: revert;
}
@position-try --bottom-right {
  /* Finally, try to align the top, right edge of the target
     with the bottom, right edge of the anchor. */
  top: anchor(bottom);
  right: anchor(right);
  width: 100px;
  height: 100px;
  bottom: revert;
  left: revert;
}With polyfill applied, the following positions are attempted in order:
flip-block flip-inline, flipping across both the
            block and inline axis, and align the top, right edge of the target
            with the bottom, left edge of the anchor.
          flip-inline --bottom-left-combined, flipping
            across the block axis, and align the top, right edge of the target
            with the bottom, right edge of the anchor.
          #my-anchor-try-tactics-combined {
  anchor-name: --my-anchor-try-tactics-combined;
}
#my-target-try-tactics-combined {
  position: absolute;
  position-anchor: --my-anchor-try-tactics-combined;
  bottom: anchor(top);
  left: anchor(right);
  position-try: flip-block flip-inline, flip-inline --bottom-left-combined;
}
@position-try --bottom-left-combined {
  top: anchor(bottom);
  left: anchor(left);
  bottom: revert;
}anchor() [scrolling elements]
      With polyfill applied: The Inner-anchored Target is positioned at the top right corner of the Anchor. The Outer-anchored Target is positioned at the bottom left corner of the Anchor.
#scroll-anchor {
  anchor-name: --scroll-anchor;
}
#inner-anchored {
  position: absolute;
  bottom: anchor(--scroll-anchor top);
  left: anchor(--scroll-anchor end);
}
#outer-anchored {
  position: absolute;
  top: anchor(--scroll-anchor bottom);
  right: anchor(--scroll-anchor start);
}anchor() [used in
        calc() function]
      With polyfill applied: Target’s left edge is 10px left of the Anchor’s right edge). The top edge of the Target is 10px below the bottom edge of the Anchor.
#my-anchor-math {
  anchor-name: --my-anchor-math;
}
#my-target-math {
  --full-math: anchor(--my-anchor-math 100%);
  --full-minus-math: calc(anchor(--my-anchor-math 100%) - 10px);
  position: absolute;
  top: calc(var(--full-math) + 10px);
  left: var(--full-minus-math);
}anchor() [passed through CSS custom
        property]
      With polyfill applied: Target’s top edge is positioned at 50% of the height of the Anchor. The right edge of the Target lines up with 100% of the width of the Anchor (i.e. the Anchor’s right edge).
#my-anchor {
  anchor-name: --my-anchor;
}
#my-target {
  --center: anchor(--my-anchor 50%);
  --full: anchor(--my-anchor 100%);
  position: absolute;
  top: var(--center);
  right: var(--full);
}anchor() [passed through multiple CSS
        custom properties]
      With polyfill applied: Target’s left edge is positioned in Anchor’s horizontal center. Target’s bottom edge is 10% above the bottom edge of Anchor.
#my-anchor-props {
  anchor-name: --my-anchor-props;
}
#my-target-props {
  --half: anchor(--my-anchor-props 50%);
  --quarter: calc(var(--half) / 2);
  --tenth: calc(var(--quarter) / 2.5);
  position: absolute;
  left: var(--half);
  bottom: var(--tenth);
}anchor() [with duplicate CSS custom
        properties]
      With polyfill applied: Target’s top left corner is positioned in the center (vertically and horizontally) of the Anchor.
#anchor-duplicate-custom-props {
  anchor-name: --anchor-duplicate-custom-props;
}
#target-duplicate-custom-props {
  --center: anchor(--anchor-duplicate-custom-props 50%);
  position: absolute;
  top: var(--center);
  left: var(--center);
}
#other {
  --center: anchor(--anchor-duplicate-custom-props 100%);
}position-area
      
        With polyfill applied: Target is positioned to the top right of the
        Anchor. See more examples of
        position-area.
      
#position-area .anchor {
  anchor-name: --position-area-anchor;
}
#position-area .target {
  position: absolute;
  position-area: top right;
  position-anchor: --position-area-anchor;
}anchor-size()
      With polyfill applied: Target has the same width as the Anchor.
#my-anchor-size {
  anchor-name: --my-anchor;
  width: 5em;
}
#my-target-size {
  width: anchor-size(--my-anchor width);
}anchor-size() on margin and inset
      
        With polyfill applied: Target's margin is the height of the
        anchor, and its right inset is the width of the anchor.
      
#my-anchor-anchor-size-extended {
  anchor-name: --my-anchor-size-extended;
  resize: both;
  overflow: hidden;
}
#my-target-anchor-size-extended {
  position: absolute;
  position-anchor: --my-anchor-size-extended;
  right: anchor-size(width);
  margin: anchor-size(height);
}
        With polyfill applied: Target and Anchor’s right edges line up. Target’s
        top edge lines up with the bottom edge of the Anchor.
        
        
        When Anchor width is changed dynamically, Target position updates
        accordingly.
      
#my-anchor-update {
  anchor-name: --my-anchor-update;
}
#my-target-update {
  position: absolute;
  right: anchor(--my-anchor-update right);
  top: anchor(--my-anchor-update bottom);
}With polyfill applied: Target A is positioned at Anchor’s top left corner. Target B is positioned at Anchor’s bottom right corner.
#my-anchor-name-list {
  anchor-name: --my-anchor-name-a, --my-anchor-name-b;
}
#my-target-name-list-a {
  position: absolute;
  right: anchor(--my-anchor-name-a left);
  bottom: anchor(--my-anchor-name-a top);
}
#my-target-name-list-b {
  position: absolute;
  left: anchor(--my-anchor-name-b right);
  top: anchor(--my-anchor-name-b bottom);
}
With polyfill applied: Target one is positioned at the bottom right corner of Anchor one. Target two is positioned at the bottom right corner of Anchor two.
#my-anchor-absolute-one,
#my-anchor-absolute-two {
  position: absolute;
  anchor-name: --my-anchor-absolute;
}
#my-target-absolute-one,
#my-target-absolute-two {
  position: absolute;
  top: anchor(--my-anchor-absolute bottom);
  left: anchor(--my-anchor-absolute right);
}
        Target is positioned at the bottom right corner of the Anchor’s
        ::before pseudo-element.
      
#my-anchor-pseudo-element::before {
  content: '::before';
  anchor-name: --my-anchor-pseudo-element;
}
#my-target-pseudo-element {
  position: absolute;
  position-anchor: --my-anchor-pseudo-element;
  top: anchor(bottom);
  left: anchor(right);
}With polyfill applied: Target and Screen Anchor’s right and top edges line up.
@media print {
  #my-print-anchor-media-query {
    anchor-name: --my-anchor-media-query;
  }
}
#my-anchor-media-query {
  anchor-name: --my-anchor-media-query;
}
#my-target-media-query {
  position: absolute;
  top: anchor(--my-anchor-media-query top);
  right: anchor(--my-anchor-media-query right);
}<style>)
        <link>)
        With polyfill applied: Target 1, 2, and 3 are positioned at Anchor’s top-left, top-right, and bottom-right corners respectively.
<style id="my-style-manual-anchor">
  #my-anchor-manual {
    anchor-name: --my-anchor-manual;
  }
</style>
<style id="my-style-manual-style-el">
  #my-target-manual-style-el {
    position: absolute;
    bottom: anchor(--my-anchor-manual top);
    right: anchor(--my-anchor-manual left);
  }
</style>
<link rel="stylesheet" href="/anchor-manual.css" id="my-style-manual-link-el" />
<!--
CSS inside the anchor-manual.css file:
#my-target-manual-link-el {
  position: absolute;
  bottom: anchor(--my-anchor-manual top);
  left: anchor(--my-anchor-manual right);
}
-->
<div id="my-anchor-manual" class="anchor">...</div>
<div id="my-target-manual-style-el" class="target">...</div>
<div id="my-target-manual-link-el" class="target">...</div>
<div id="my-target-manual-inline-style" class="target"
  style="position: absolute;
    top: anchor(--my-anchor-manual bottom);
    left: anchor(--my-anchor-manual right);"
>...</div>
<script>
  polyfill({
    elements: [
      // The <style> element for anchor
      document.getElementById('my-style-manual-anchor'),
      // The <style> element
      document.getElementById('my-style-manual-style-el'),
      // The <link> element
      document.getElementById('my-style-manual-link-el'),
      // The target element with inline styles
      document.getElementById('my-target-manual-inline-style'),
    ],
  });
</script>With polyfill applied: Targets are positioned to the right of their corresponding item’s arrow.
#anchor-scope li {
  anchor-scope: --anchor-scope;
}
#anchor-scope .arrow {
  anchor-name: --anchor-scope;
}
#anchor-scope .target {
  position: absolute;
  position-anchor: --anchor-scope;
  left: anchor(right);
  top: anchor(center);
}With polyfill applied: Target and Anchor text is orange (from styles defined in an imported stylesheet). Target One is positioned at the bottom right corner of the Anchor. The Anchor has an envelope icon on both sides of the text.
          Note: Target Two has
          position-area defined in an imported stylesheet, which is
          not parsed by the polyfill, so it is not positioned correctly. It
          should be positioned at the bottom left corner.
        
@import url('./import-is-imported-url.css') supports(display: grid) screen and (min-width: 400px);
@import './import-is-imported-string.css';
#imports .anchor::after {
  content: url('./mail.svg');
}
/* ./import-is-imported-url.css */
#imports #target-1 {
  color: var(--brand-orange);
}
#imports #target-2 {
  position-area: block-end inline-start;
  color: var(--brand-orange);
}
#imports .anchor::before {
  content: url('./mail.svg');
}
/* ./import-is-imported-string.css */
#imports .anchor {
  color: var(--brand-orange);
}The polyfill can position targets and anchors inside a shadow root. See shadow DOM examples.
At OddBird, we love contributing to the languages & tools developers rely on. We’re currently working on polyfills for new Popover & Anchor Positioning functionality, as well as CSS specifications for functions, mixins, and responsive typography. Help us keep this work sustainable and centered on your needs as a developer! We display sponsor logos and avatars on our website.
Sponsor OddBird’s OSS Work