![Una Kravets](https://web.dev/images/authors/unakravets.jpg) Una Kravets [X](https://twitter.com/una) [Mastodon](https://front-end.social/@una) [Homepage](https://una.im)

<br />

The CSS Anchor Positioning API lets you position elements relative to other elements, known as *anchors*. This API simplifies complex layout requirements for many interface features like menus and submenus, tooltips, selects, labels, cards, settings dialogs, and many more. With anchor positioning built into the browser, you can build layered user interfaces without relying on third-party libraries, opening a world of creative possibilities.


Browser Support

- ![Chrome: 125.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='-10 -10 276 276'%3E%3ClinearGradient id='a' x1='145' x2='34' y1='253' y2='61' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%231e8e3e'/%3E%3Cstop offset='1' stop-color='%2334a853'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='111' x2='222' y1='254' y2='62' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fcc934'/%3E%3Cstop offset='1' stop-color='%23fbbc04'/%3E%3C/linearGradient%3E%3ClinearGradient id='c' x1='17' x2='239' y1='80' y2='80' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23d93025'/%3E%3Cstop offset='1' stop-color='%23ea4335'/%3E%3C/linearGradient%3E%3Ccircle cx='128' cy='128' r='64' fill='%23fff'/%3E%3Cpath fill='url(%23a)' d='M96 183a64 64 0 0 1-23-23L17 64a128 128 0 0 0 111 192l55-96a64 64 0 0 1-87 23Z'/%3E%3Cpath fill='url(%23b)' d='M192 128a64 64 0 0 1-9 32l-55 96A128 128 0 0 0 239 64H128a64 64 0 0 1 64 64Z'/%3E%3Ccircle cx='128' cy='128' r='52' fill='%231a73e8'/%3E%3Cpath fill='url(%23c)' d='M96 73a64 64 0 0 1 32-9h111a128 128 0 0 0-222 0l56 96a64 64 0 0 1 23-87Z'/%3E%3C/svg%3E)
- ![Edge: 125.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 27600 27600'%3E%3ClinearGradient id='A' gradientUnits='userSpaceOnUse'/%3E%3ClinearGradient id='B' x1='6870' x2='24704' y1='18705' y2='18705' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%230c59a4'/%3E%3Cstop offset='1' stop-color='%23114a8b'/%3E%3C/linearGradient%3E%3ClinearGradient id='C' x1='16272' x2='5133' y1='10968' y2='23102' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%231b9de2'/%3E%3Cstop offset='.16' stop-color='%231595df'/%3E%3Cstop offset='.67' stop-color='%230680d7'/%3E%3Cstop offset='1' stop-color='%230078d4'/%3E%3C/linearGradient%3E%3CradialGradient id='D' cx='16720' cy='18747' r='9538' xlink:href='%23A'%3E%3Cstop offset='.72' stop-opacity='0'/%3E%3Cstop offset='.95' stop-opacity='.53'/%3E%3Cstop offset='1'/%3E%3C/radialGradient%3E%3CradialGradient id='E' cx='7130' cy='19866' r='14324' gradientTransform='matrix(.14843 -.98892 .79688 .1196 -8759 25542)' xlink:href='%23A'%3E%3Cstop offset='.76' stop-opacity='0'/%3E%3Cstop offset='.95' stop-opacity='.5'/%3E%3Cstop offset='1'/%3E%3C/radialGradient%3E%3CradialGradient id='F' cx='2523' cy='4680' r='20243' gradientTransform='matrix(-.03715 .99931 -2.12836 -.07913 13579 3530)' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%2335c1f1'/%3E%3Cstop offset='.11' stop-color='%2334c1ed'/%3E%3Cstop offset='.23' stop-color='%232fc2df'/%3E%3Cstop offset='.31' stop-color='%232bc3d2'/%3E%3Cstop offset='.67' stop-color='%2336c752'/%3E%3C/radialGradient%3E%3CradialGradient id='G' cx='24247' cy='7758' r='9734' gradientTransform='matrix(.28109 .95968 -.78353 .22949 24510 -16292)' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%2366eb6e'/%3E%3Cstop offset='1' stop-color='%2366eb6e' stop-opacity='0'/%3E%3C/radialGradient%3E%3Cpath id='H' d='M24105 20053a9345 9345 0 01-1053 472 10202 10202 0 01-3590 646c-4732 0-8855-3255-8855-7432 0-1175 680-2193 1643-2729-4280 180-5380 4640-5380 7253 0 7387 6810 8137 8276 8137 791 0 1984-230 2704-456l130-44a12834 12834 0 006660-5282c220-350-168-757-535-565z'/%3E%3Cpath id='I' d='M11571 25141a7913 7913 0 01-2273-2137 8145 8145 0 01-1514-4740 8093 8093 0 013093-6395 8082 8082 0 011373-859c312-148 846-414 1554-404a3236 3236 0 012569 1297 3184 3184 0 01636 1866c0-21 2446-7960-8005-7960-4390 0-8004 4166-8004 7820 0 2319 538 4170 1212 5604a12833 12833 0 007684 6757 12795 12795 0 003908 610c1414 0 2774-233 4045-656a7575 7575 0 01-6278-803z'/%3E%3Cpath id='J' d='M16231 15886c-80 105-330 250-330 566 0 260 170 512 472 723 1438 1003 4149 868 4156 868a5954 5954 0 003027-839 6147 6147 0 001133-850 6180 6180 0 001910-4437c26-2242-796-3732-1133-4392-2120-4141-6694-6525-11668-6525-7011 0-12703 5635-12798 12620 47-3654 3679-6605 7996-6605 350 0 2346 34 4200 1007 1634 858 2490 1894 3086 2921 618 1067 728 2415 728 2952s-271 1333-780 1990z'/%3E%3Cuse fill='url(%23B)' xlink:href='%23H'/%3E%3Cuse fill='url(%23D)' opacity='.35' xlink:href='%23H'/%3E%3Cuse fill='url(%23C)' xlink:href='%23I'/%3E%3Cuse fill='url(%23E)' opacity='.4' xlink:href='%23I'/%3E%3Cuse fill='url(%23F)' xlink:href='%23J'/%3E%3Cuse fill='url(%23G)' xlink:href='%23J'/%3E%3C/svg%3E)
- ![Firefox: 147.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 512 512'%3E%3Cdefs%3E%3CradialGradient id='ff-b' cx='428.5' cy='55.1' r='501' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23ffbd4f'/%3E%3Cstop offset='.2' stop-color='%23ffac31'/%3E%3Cstop offset='.3' stop-color='%23ff9d17'/%3E%3Cstop offset='.3' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff563b'/%3E%3Cstop offset='.5' stop-color='%23ff3750'/%3E%3Cstop offset='.7' stop-color='%23f5156c'/%3E%3Cstop offset='.8' stop-color='%23eb0878'/%3E%3Cstop offset='.9' stop-color='%23e50080'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-c' cx='245.4' cy='259.9' r='501' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.3' stop-color='%23960e18'/%3E%3Cstop offset='.3' stop-color='%23b11927' stop-opacity='.7'/%3E%3Cstop offset='.4' stop-color='%23db293d' stop-opacity='.3'/%3E%3Cstop offset='.5' stop-color='%23f5334b' stop-opacity='.1'/%3E%3Cstop offset='.5' stop-color='%23ff3750' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-d' cx='305.8' cy='-58.6' r='363' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.3' stop-color='%23ffdc3e'/%3E%3Cstop offset='.5' stop-color='%23ff9d12'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-e' cx='190' cy='390.8' r='238.6' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.3' stop-color='%233a8ee6'/%3E%3Cstop offset='.5' stop-color='%235c79f0'/%3E%3Cstop offset='.7' stop-color='%239059ff'/%3E%3Cstop offset='1' stop-color='%23c139e6'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-f' cx='252.2' cy='201.3' r='126.5' gradientTransform='matrix(1 0 0 1 -48 31)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.2' stop-color='%239059ff' stop-opacity='0'/%3E%3Cstop offset='.3' stop-color='%238c4ff3' stop-opacity='.1'/%3E%3Cstop offset='.8' stop-color='%237716a8' stop-opacity='.5'/%3E%3Cstop offset='1' stop-color='%236e008b' stop-opacity='.6'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-g' cx='239.1' cy='34.6' r='171.6' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23ffe226'/%3E%3Cstop offset='.1' stop-color='%23ffdb27'/%3E%3Cstop offset='.3' stop-color='%23ffc82a'/%3E%3Cstop offset='.5' stop-color='%23ffa930'/%3E%3Cstop offset='.7' stop-color='%23ff7e37'/%3E%3Cstop offset='.8' stop-color='%23ff7139'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-h' cx='374' cy='-74.3' r='732.2' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3Cstop offset='.6' stop-color='%23ff5634'/%3E%3Cstop offset='.7' stop-color='%23ff3647'/%3E%3Cstop offset='.9' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-i' cx='304.6' cy='7.1' r='536.4' gradientTransform='rotate(84 303 4)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff44f'/%3E%3Cstop offset='.1' stop-color='%23ffe847'/%3E%3Cstop offset='.2' stop-color='%23ffc830'/%3E%3Cstop offset='.3' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff8b16'/%3E%3Cstop offset='.5' stop-color='%23ff672a'/%3E%3Cstop offset='.6' stop-color='%23ff3647'/%3E%3Cstop offset='.7' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-j' cx='235' cy='98.1' r='457.1' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3Cstop offset='.6' stop-color='%23ff5634'/%3E%3Cstop offset='.7' stop-color='%23ff3647'/%3E%3Cstop offset='.9' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-k' cx='355.7' cy='124.9' r='500.3' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.2' stop-color='%23ffe141'/%3E%3Cstop offset='.5' stop-color='%23ffaf1e'/%3E%3Cstop offset='.6' stop-color='%23ff980e'/%3E%3C/radialGradient%3E%3ClinearGradient id='ff-a' x1='446.9' y1='76.8' x2='47.9' y2='461.8' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.1' stop-color='%23ffe847'/%3E%3Cstop offset='.2' stop-color='%23ffc830'/%3E%3Cstop offset='.4' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff8b16'/%3E%3Cstop offset='.5' stop-color='%23ff672a'/%3E%3Cstop offset='.5' stop-color='%23ff3647'/%3E%3Cstop offset='.7' stop-color='%23e31587'/%3E%3C/linearGradient%3E%3ClinearGradient id='ff-l' x1='442.1' y1='74.8' x2='102.6' y2='414.3' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.2' stop-color='%23fff44f' stop-opacity='.8'/%3E%3Cstop offset='.3' stop-color='%23fff44f' stop-opacity='.6'/%3E%3Cstop offset='.5' stop-color='%23fff44f' stop-opacity='.2'/%3E%3Cstop offset='.6' stop-color='%23fff44f' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M479 166c-11-25-32-52-49-60a249 249 0 0 1 25 73c-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-60 35-81 101-83 134a120 120 0 0 0-66 25 71 71 0 0 0-6-5 111 111 0 0 1-1-58c-25 11-44 29-58 44-9-12-9-52-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73l-1 2-2 15a229 229 0 0 0-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121zM202 355l3 1-3-1zm55-145zm198-31z' fill='url(%23ff-a)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60 14 26 22 53 25 72v1a207 207 0 0 1-206 279c-113-3-212-87-231-197-3-17 0-26 2-40-2 11-3 14-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121z' fill='url(%23ff-b)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60 14 26 22 53 25 72v1a207 207 0 0 1-206 279c-113-3-212-87-231-197-3-17 0-26 2-40-2 11-3 14-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121z' fill='url(%23ff-c)'/%3E%3Cpath d='m362 195 1 1a130 130 0 0 0-22-29C266 92 322 5 331 0c-60 35-81 101-83 134l9-1c45 0 84 25 105 62z' fill='url(%23ff-d)'/%3E%3Cpath d='M257 210c-1 6-22 26-29 26-68 0-80 41-80 41 3 35 28 64 57 79l4 2 7 3a107 107 0 0 0 31 6c120 6 143-143 57-186 22-4 45 5 58 14-21-37-60-62-105-62l-9 1a120 120 0 0 0-66 25l17 16c16 16 58 33 58 35z' fill='url(%23ff-e)'/%3E%3Cpath d='M257 210c-1 6-22 26-29 26-68 0-80 41-80 41 3 35 28 64 57 79l4 2 7 3a107 107 0 0 0 31 6c120 6 143-143 57-186 22-4 45 5 58 14-21-37-60-62-105-62l-9 1a120 120 0 0 0-66 25l17 16c16 16 58 33 58 35z' fill='url(%23ff-f)'/%3E%3Cpath d='m171 151 5 3a111 111 0 0 1-1-58c-25 11-44 29-58 44 1 0 36 0 54 11z' fill='url(%23ff-g)'/%3E%3Cpath d='M18 261a242 242 0 0 0 231 197 207 207 0 0 0 206-279c8 56-20 110-64 146-86 71-169 43-186 31l-3-1c-50-24-71-70-67-110-42 0-57-35-57-35s38-28 89-4c46 22 90 4 90 4 0-2-42-19-58-35l-17-16a71 71 0 0 0-6-5l-5-3c-18-11-52-11-54-11-9-12-9-51-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73c0 1-9 38-5 57z' fill='url(%23ff-h)'/%3E%3Cpath d='M341 167a130 130 0 0 1 22 29 46 46 0 0 1 4 3c55 50 26 121 24 126 44-36 72-90 64-146-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-9 5-65 92 10 167z' fill='url(%23ff-i)'/%3E%3Cpath d='M367 199a46 46 0 0 0-4-3l-1-1c-13-9-36-18-58-15 86 44 63 193-57 187a107 107 0 0 1-31-6 131 131 0 0 1-11-5c17 12 99 39 186-31 2-5 31-76-24-126z' fill='url(%23ff-j)'/%3E%3Cpath d='M148 277s12-41 80-41c7 0 28-20 29-26s-44 18-90-4c-51-24-89 4-89 4s15 35 57 35c-4 40 16 85 67 110l3 1c-29-15-54-44-57-79z' fill='url(%23ff-k)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60a249 249 0 0 1 25 73c-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-60 35-81 101-83 134l9-1c45 0 84 25 105 62-13-9-36-18-58-14 86 43 63 192-57 186a107 107 0 0 1-31-6 131 131 0 0 1-11-5l-3-1 3 1c-29-15-54-44-57-79 0 0 12-41 80-41 7 0 28-20 29-26 0-2-42-19-58-35l-17-16a71 71 0 0 0-6-5 111 111 0 0 1-1-58c-25 11-44 29-58 44-9-12-9-52-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73l-1 2-2 15a279 279 0 0 0-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121zm-24 13z' fill='url(%23ff-l)'/%3E%3C/svg%3E)
- ![Safari: 26.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='195 190 135 135'%3E%3Cdefs%3E%3ClinearGradient id='s-a' x1='132.6' x2='134.4' y1='111.7' y2='-105.3' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23d2d2d2' /%3E%3Cstop offset='.5' stop-color='%23f2f2f2' /%3E%3Cstop offset='1' stop-color='%23fff' /%3E%3C/linearGradient%3E%3ClinearGradient id='s-b' gradientUnits='userSpaceOnUse' /%3E%3ClinearGradient id='s-c' x1='65.4' x2='67.4' y1='115.7' y2='17.1' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23005ad5' /%3E%3Cstop offset='.2' stop-color='%230875f0' /%3E%3Cstop offset='.3' stop-color='%23218cee' /%3E%3Cstop offset='.6' stop-color='%2327a5f3' /%3E%3Cstop offset='.8' stop-color='%2325aaf2' /%3E%3Cstop offset='1' stop-color='%2321aaef' /%3E%3C/linearGradient%3E%3ClinearGradient id='s-d' x1='158.7' x2='176.3' y1='96.7' y2='79.5' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23c72e24' /%3E%3Cstop offset='1' stop-color='%23fd3b2f' /%3E%3C/linearGradient%3E%3CradialGradient id='s-i' cx='-69.9' cy='69.3' r='54' gradientTransform='matrix(.9 -.01 .04 2.72 -9 -120)' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%2324a5f3' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%231e8ceb' /%3E%3C/radialGradient%3E%3CradialGradient id='s-j' cx='109.3' cy='13.8' r='93.1' gradientTransform='matrix(-.02 1.1 -1.04 -.02 137 -115)' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%235488d6' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%235d96eb' /%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='220' height='220' x='22' y='-107' fill='url(%23s-a)' ry='49' transform='matrix(.57 0 0 .57 187 256)' /%3E%3Cg transform='translate(194 190)'%3E%3Ccircle cx='67.8' cy='67.7' fill='url(%23s-c)' paint-order='stroke fill markers' r='54' /%3E%3Ccircle cx='-69.9' cy='69.3' fill='url(%23s-i)' transform='translate(138 -2)' r='54' /%3E%3C/g%3E%3Cellipse cx='120' cy='14.2' fill='url(%23s-j)' rx='93.1' ry='93.7' transform='matrix(.58 0 0 .58 192 250)' /%3E%3Cg transform='matrix(.58 0 0 .57 197 182)'%3E%3Cpath fill='%23cac7c8' d='M46 192h1l72-48-7-9-66 57Z' /%3E%3Cpath fill='%23fbfffc' d='M46 191v1l66-57-7-9-59 65Z' /%3E%3Cpath fill='url(%23s-d)' d='m119 144-7-9 66-57-59 66Z' /%3E%3Cpath fill='%23fb645c' d='m105 126 7 9 66-57-1-1-72 49Z' /%3E%3C/g%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-miterlimit='1' stroke-width='1.3' d='m287 278 3-2m-12-17 8-2m-8-3h4m-4-13 8 2m-8 3h4m-1-13 7 3m-4-11 7 4m-2-11 6 6m0-12 6 7m1-11 4 6m4-10 3 7m5-9 2 7m15-7-1 7m10-5-3 7m11-4-4 7m11-2-5 6m16 7-7 4m10 4-7 3m10 6-8 1m8 16-8-2m5 10-7-3m4 11-7-4m2 11-6-5m0 11-5-6m-2 11-4-7m-4 11-3-8m-6 10-1-8m-16 8 2-8m-10 5 3-7m-11 4 4-7m-11 2 5-6m-8 3 3-3m4 8 2-3m5 8 2-4m6 7 1-4m8 5v-4m8 4v-4m9 3-1-4m9 1-2-4m9 0-2-4m9-2-3-3m8-4-3-2m8-5-4-2m7-6-4-1m5-8h-4m4-8h-4m3-9-4 1m1-9-4 2m-1-9-3 2m-2-9-3 3m-4-8-2 3m-5-8-2 4m-6-6-1 3m-8-5v4m-8-4v4m-9-2 1 3m-9 0 2 3m-9 1 2 3m-9 2 3 3m-8 4 3 2m-8 5 4 2m-7 6 4 1m-4 25 4-1m-2 5 7-3m-6 7 4-2m-2 6 7-4m-13-21h8m41-41v-8m0 99v-8m49-42h-8' transform='translate(-65 8)' /%3E%3C/svg%3E)

[Source](https://developer.mozilla.org/docs/Web/CSS/Reference/Values/anchor)

<br />

## Core Concepts: Anchors and positioned elements

At the heart of this API lies the relationship between *anchors* and *positioned elements* . An anchor is an element designated as a reference point using the `anchor-name` property. A positioned element is an element placed relative to an anchor using the `position-anchor` property or explicitly using `anchor-name` in its positioning logic.
![](https://developer.chrome.com/docs/css-ui/image/anchor-diagram-0.png) Anchor elements and positioned elements.

## Set up anchors

Creating an anchor is straightforward. Apply the anchor-name property to the selected element, and assign it a unique identifier. This unique identifier must be prepended with a double dash, much like a CSS variable.

```css
.anchor-button {
    anchor-name: --anchor-el;
}
```

Once assigned an anchor-name, `.anchor-button` serves as an anchor, ready to guide the placement of other elements. You can connect this anchor to other elements in one of two ways:

### Implicit anchors

The first way to connect an anchor to another element is with an *implicit anchor* as in the following code example. The `position-anchor` property is added to the element you want to connect to your anchor, and has the name of the anchor (in this case `--anchor-el`) as a value.

```css
.positioned-notice {
    position-anchor: --anchor-el;
}
```

With an implicit anchor relationship, you can position elements using the `anchor()` function without explicitly specifying the anchor name at its first argument.

```css
.positioned-notice {
    position-anchor: --anchor-el;
    top: anchor(bottom);
}
```

### Explicit anchors

Alternatively, you can use the anchor name directly in the anchor function (for example, `top: anchor(--anchor-el bottom`). This is called an **explicit anchor**, and can be handy if you want to anchor to multiple elements (read on for an example).

```css
.positioned-notice {
    top: anchor(--anchor-el bottom);
}
```

## Position elements relative to anchors

![](https://developer.chrome.com/docs/css-ui/image/anchor-diagram-1.png) Anchor positioning diagram with physical properties.

Anchor positioning builds on CSS absolute positioning To use positioning values you need to add `position: absolute` to your positioned element. Then, use the `anchor()` function to apply positioning values. For example, to position an anchored element at the top left of the anchoring element, use the following positioning:

```css
.positioned-notice {
    position-anchor: --anchor-el;
    /* absolutely position the positioned element */
    position: absolute;
    /* position the right of the positioned element at the right edge of the anchor */
    right: anchor(right);
    /* position the bottom of the positioned element at the top edge of the anchor */
    bottom: anchor(top);
}
```
![](https://developer.chrome.com/docs/css-ui/image/anchor-diagram-2.png) Diagram of positioning edges on the positioned element.

Now you have one element anchored to another, like so:
<iframe height="400" style="width: 100%;" scrolling="no" title="Base anchor demo -- non popover" src="https://codepen.io/web-dot-dev/embed/GRaRyKm?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/GRaRyKm">
Base anchor demo -- non popover</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo of a basic anchor.

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/anchor-demo-1.png)

To use logical positioning for these values, the equivalents are as follows:

- `top` = `inset-block-start`
- `left`= `inset-inline-start`
- `bottom` = `inset-block-end`
- `right`= `inset-inline-end`

### Center a positioned element with `anchor-center`

To make it easier to center your anchor positioned element relative to its anchor, there's a new value called `anchor-center` which can be used with the `justify-self`, `align-self`, `justify-items`, and `align-items` properties.

This example modifies the previous one by using `justify-self: anchor-center` to center the positioned element on top of its anchor.

```css
.positioned-notice {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of positioned elem at top of anchor  */
  bottom: anchor(top);
  /*  Center justification to the anchor */
  justify-self: anchor-center;
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="Base anchor demo -- non popover" src="https://codepen.io/web-dot-dev/embed/GRaRyov?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/GRaRyov">
Base centered anchor demo -- non popover</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo of an anchor centered using `justify-center`.

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/anchor-demo-2.png)

### Multiple anchors

Elements can be tethered to more than one anchor. This means you may need to set position values that are positioned relative to more than one anchor. Do this by using the `anchor()` function and explicitly stating which anchor you are referencing in the first argument. In the following example, the top-left of a positioned element is anchored to the bottom-right of one anchor, and the bottom-right of the positioned element is anchored to the top-left of the second anchor:

```css
.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="Base anchor demo -- non popover" src="https://codepen.io/web-dot-dev/embed/eYaYyJa?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/eYaYyJa">Multiple anchors</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo showing multiple anchors.

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/anchor-demo-3.png)

## Position with `position-area`

The anchoring API includes a new layout mechanism using the `position-area` property.

This property lets you place anchor positioned elements relative to their respective anchors, and works on a 9-cell grid with the anchoring element in the center.

To use `position-area` rather than absolute positioning, use the `position-area` property, with physical or logical values. For example:

- Top-center: `position-area: top` or `position-area: block-start`
- Left-center: `position-area: left` or `position-area: inline-start`
- Bottom-center: `position-area: bottom` or `position-area: block-end`
- Right-center: `position-area: right` or `position-area: inline-end`

<iframe height="400" style="width: 100%;" scrolling="no" title="Base anchor demo -- non popover" src="https://codepen.io/web-dot-dev/embed/pomopyq?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/pomopyq">Multiple anchors</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo showing multiple anchors.

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/position-area.png)

To explore these positions further, check out the following tool:
<iframe height="580" style="border: 2px solid dimgray; width: 100%" scrolling="no" title="Anchor tool" src="https://chrome.dev/anchor-tool" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"></iframe> Anchor tool for position-area positions.

## Size elements with `anchor-size()`

The `anchor-size()` function, also part of the anchor positioning API, can be used to size or position an anchor positioned element based on the size of its anchor (width, height, or inline and block sizes).

The following CSS shows an example of using this for height,using `anchor-size(height)` within a `calc()` function to set the maximum height of the tooltip to be two times the height of the anchor.

```css
.positioned-notice {
  position-anchor: --question-mark;

  /*  set max height of the tooltip to 2x height of the anchor  */
  max-height: calc(anchor-size(height) * 2);
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="Anchor-size() demo" src="https://codepen.io/web-dot-dev/embed/BaeaJzr?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/BaeaJzr">Anchor-size() demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo for `anchor-size`

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/anchor-demo-5.png)

## Use anchor with top-layer elements like popover and dialog

Anchor positioning works incredibly well with top-layer elements like [`popover`](https://web.dev/blog/popover-api). and `<dialog>`. While these elements are placed in a separate layer from the rest of the DOM subtree, anchor positioning lets you tether them back to, and scroll along with elements not in the top layer. This is a huge win for layered interfaces.

In the following example, a set of tooltip popovers are triggered open using a button. The button is the anchor and the tooltip is the positioned element. You can style the positioned element just like any other anchored element. For this specific example, the `anchor-name` and `position-anchor` are inline styles on the button and tooltip. Because each anchor needs a unique anchor name, when generating dynamic content, inlining is the easiest way to do this.
<iframe height="400" style="width: 100%;" scrolling="no" title="Tooltip demo" src="https://codepen.io/web-dot-dev/embed/OJYJzRQ?default-tab=Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/OJYJzRQ">Tooltip demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo using anchor with `popover`

![Screenshot of the demo.](https://developer.chrome.com/static/docs/css-ui/anchor-positioning-api/image/anchor-demo-6.png)

> [!NOTE]
> **Note:** popover and dialog elements user agent styles which center them in the viewport by default. You may run into layout issues because of this. For all anchor positioned elements, I would recommend you reset those styles using `inset: auto` to prevent confusion. This may [change](https://github.com/w3c/csswg-drafts/issues/10258) in the future to be a default user agent style.

## Adjust anchor positions with `@position-try`

Once you have your initial anchor position, you may want to adjust the position if the anchor reaches the edges of its containing block. To create alternative anchor positions, you can use the `@position-try` directive along with the `position-try-fallbacks` property.

In the following example, a submenu appears to the right of a menu. Menus and submenus are a great use of the anchor positioning API along with the [popover attribute](https://web.dev/blog/popover-api), as these menus tend to be anchored to a trigger button.

For this submenu, if there's not enough space horizontally, you can move it underneath the menu instead. To do this, first set up the initial position:

```css
#submenu {
  position: absolute;
  position-anchor: --submenu;

  /* initial position */
  margin-left: var(--padding);
  position-area: right span-bottom;
}
```

Then, set up your fallback anchored positions using `@position-try`:

```css
/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  posotion-area: bottom;
}
```

Finally, connect the two with `position-try-fallbacks`. All together, it looks like this:

```css
#submenu {
  position: absolute;
  position-anchor: --submenu;
  /* initial position */
  margin-left: var(--padding);
  position-area: right span-bottom;
  */ connect with position-try-fallbacks */
  position-try-fallbacks: --bottom;
}

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  position-area: bottom;
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="Anchored submenu demo" src="https://codepen.io/web-dot-dev/embed/mdYdpOM?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/mdYdpOM">Anchored submenu demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Demo using anchor with `popover`

> [!NOTE]
> **Note:** At this time, you can animate `position-try-fallbacks` if you are applying styles using positioned values, which can be transitioned with the `transition` property, such as in the demo here. `position-area` is not transitionable yet, but the Chrome team is working on a solution.

## Anchor position auto-flip keywords

If you have a basic adjustment, such as flipping from top to bottom or left to right (or both), you can even skip the step of creating custom `@position-try` declarations and use the built-in browser-supported flip keywords like `flip-block` and `flip-inline`. These work as stand-ins for custom `@position-try` declarations, and can be used in combination with each other:

```css
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
```

Flip keywords can significantly simplify your anchor code. With just a few lines, you can create a fully-functional anchor with alternative positions:

```css
#my-tooltip {
  position-anchor: --question-mark;
  position-area: top;
  position-try-fallbacks: flip-block;
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="Auto flip demo" src="https://codepen.io/web-dot-dev/embed/wvbvyGb?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/wvbvyGb">Auto flip demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> Using auto flip with `position-try-fallbacks: flip-block`

## `position-visibility` for anchors in subscrollers

There are some cases in which you may want to anchor an element within a subscroller of the page. In these instances, you can control the visibility of the anchor using `position-visibility`. When does the anchor stay in view? When does it disappear? You have control over these options with this feature. You use `position-visibility: anchors-visible` when you want the positioned element to stay in view until the anchor is out of view:

```css
#tooltip {
  position: fixed;
  position-anchor: --anchor-top-anchor;
  position-visibility: anchors-visible;
  bottom: anchor(top);
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="position-visibility demo" src="https://codepen.io/web-dot-dev/embed/qBGBxRx?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/qBGBxRx">position-visibility demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> `position-visibility: anchors-visible` Demo

Alternatively, you use `position-visibility: no-overflow` to prevent the anchor from overflowing its container.

```css
#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}
```
<iframe height="400" style="width: 100%;" scrolling="no" title="position-visibility demo" src="https://codepen.io/web-dot-dev/embed/pomoaPy?default-tab=css%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/web-dot-dev/pen/pomoaPy">position-visibility demo</a> by web.dev (<a href="https://codepen.io/web-dot-dev">@web-dot-dev</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe> `position-visibility: no-overflow` Demo

## Feature detection and polyfilling

Because browser support is limited at this time, you likely want to use this API with some precautions. First, you can check for support directly in CSS by using the [`@supports`](https://developer.mozilla.org/docs/Web/CSS/@supports) feature query. The way to do this is to wrap your anchor styles in the following:

```css
@supports (anchor-name: --myanchor) {

  /* Anchor styles here */

}
```

Additionally, you can polyfill the anchor positioning feature with [the CSS anchor positioning polyfill by Oddbird](https://github.com/oddbird/css-anchor-positioning), which works from Firefox 54, Chrome 51, Edge 79, and Safari 10. This polyfill supports most of the basic anchor position features, though the current implementation is not complete and contains some outdated syntax. You can use the unpkg link or import it directly in a package manager.

## A note on accessibility

While the anchor positioning API allows an element to be positioned relative to others, it doesn't inherently create any meaningful semantic relationship between them. If there actually is a semantic relationship between the anchor element and the positioned element (for example the positioned element is a sidebar comment about the anchor text), one way to do that is to use `aria-details` to point from the anchor element to the positioned element(s). Screen reader software is still learning how to deal with aria-details, but support is improving.

```html
<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
```

```css
.anchor {
  anchor-name: --anchor;
}

.positioned {
  position: fixed;
  position-anchor: --anchor;
}
```

If you are using anchor positioning with the `popover` attribute or with a `<dialog>` element, the browser will handle the focus navigation corrections for proper accessibility, so you don't need to have your popovers or dialogs in DOM order. Read more on the note on [accessibility](https://drafts.csswg.org/css-anchor-position-1/#accessibility) in the spec.

### Further reading

- [Drawing a Line to Connect Elements with CSS Anchor Positioning](https://frontendmasters.com/blog/drawing-a-line-to-connect-elements-with-css-anchor-positioning/)
- [Future CSS: Anchor positioning by Roman Komarov](https://kizu.dev/anchor-positioning-experiments/)
- [Una's Codepen Collection of Anchor demos](https://codepen.io/collection/ExkRWw)
- [Anchor positioning tool](https://chrome.dev/anchor-tool/)