{"id":8550,"date":"2026-02-16T13:44:32","date_gmt":"2026-02-16T18:44:32","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=8550"},"modified":"2026-02-16T13:44:33","modified_gmt":"2026-02-16T18:44:33","slug":"anchored-menus-and-a-lesson-in-scoping","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/anchored-menus-and-a-lesson-in-scoping\/","title":{"rendered":"Anchored Menus and a Lesson in Scoping"},"content":{"rendered":"\n<p>I had this (bad) idea. <\/p>\n\n\n\n<p>It&#8217;s related to <a href=\"https:\/\/frontendmasters.com\/blog\/popover-context-menus-with-anchor-positioning\/\">popovers and anchor-positioned menus<\/a>. I love this pairing: with only HTML and CSS we can make a button that opens\/closes anything we want. A tooltip or a menu is a wonderful use-case. <\/p>\n\n\n\n<p>This isn&#8217;t a terribly difficult thing to do, but, you have to remember a bunch of stuff and put certain unique values on certain elements exactly. <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Remember the right <code>command<\/code> attribute value on the button<\/li>\n\n\n\n<li>Put a unique <code>id<\/code> on the menu. <\/li>\n\n\n\n<li>Match up the <code>commandfor<\/code> attribute on the button to that id. <\/li>\n\n\n\n<li>Make sure the button has an unique <code>anchor-name<\/code>. <\/li>\n\n\n\n<li>Match up the <code>position-anchor<\/code> on the menu to that unique name. <\/li>\n\n\n\n<li>Make sure you&#8217;re using good anchor positioning fallbacks. <\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n  <span class=\"hljs-attr\">commandfor<\/span>=<span class=\"hljs-string\">\"menu-12345\"<\/span>\n  <span class=\"hljs-attr\">command<\/span>=<span class=\"hljs-string\">\"toggle-popover\"<\/span>\n  <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"anchor-name: --menu-button-12345;\"<\/span>\n&gt;<\/span>\n  Toggle Menu\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">menu<\/span>\n  <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"menu-12345\"<\/span>\n  <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"position-anchor: --menu-button-12345\"<\/span>\n&gt;<\/span>\n  Menu\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">menu<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>That feels like kind of a lot to remember and get right.<\/p>\n\n\n\n<p>Here&#8217;s my (bad) idea: make a quick <code>&lt;web-component&gt;<\/code> that does those things. On the surface, maybe that makes sense. It did to me. But the ridiculous part is that now it introduces JavaScript into things in a place we didn&#8217;t need JavaScript before, which makes it more fragile (and potentially render later) than it would without. <\/p>\n\n\n\n<p>So I&#8217;m not advocating for use here, but I did learn some things along the way that I found interesting and worth sharing. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Light DOM Web Component<\/h2>\n\n\n\n<p>I called it <code>&lt;a-menu&gt;<\/code> just to be short and slightly cheeky. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> { LitElement, html, css } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { customElement, property } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit\/decorators.js'<\/span>;\n\n@customElement(<span class=\"hljs-string\">'a-menu'<\/span>)\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AMenu<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">LitElement<\/span> <\/span>{\n  @property({ <span class=\"hljs-attr\">attribute<\/span>: <span class=\"hljs-string\">'button-name'<\/span> }) buttonName = <span class=\"hljs-string\">'Menu'<\/span>;\n\n  private menuId = <span class=\"hljs-string\">`menu-<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">Math<\/span>.random().toString(<span class=\"hljs-number\">36<\/span>).substr(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">9<\/span>)}<\/span>`<\/span>;\n  \n  <span class=\"hljs-comment\">\/\/ Disable the Shadow DOM<\/span>\n  createRenderRoot() {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">this<\/span>;\n  }\n\n  firstUpdated() {\n    <span class=\"hljs-keyword\">const<\/span> menu = <span class=\"hljs-keyword\">this<\/span>.querySelector(<span class=\"hljs-string\">'menu'<\/span>);\n    <span class=\"hljs-keyword\">if<\/span> (menu) {\n      menu.setAttribute(<span class=\"hljs-string\">'popover'<\/span>, <span class=\"hljs-string\">'auto'<\/span>);\n      menu.id = <span class=\"hljs-keyword\">this<\/span>.menuId;\n    }\n  }\n\n  render() {\n    <span class=\"hljs-keyword\">return<\/span> html`<span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n        a-menu {\n          display: inline-block;\n          \n          button {\n            position-anchor: --menu-button-<\/span><span class=\"hljs-subst\">${menuId}<\/span><span class=\"xml\"><span class=\"css\">;\n          }\n  \n          <span class=\"hljs-selector-tag\">menu<\/span> {\n            <span class=\"hljs-attribute\">position-anchor<\/span>: --menu-button-<\/span><\/span><span class=\"hljs-subst\">${menuId}<\/span><span class=\"xml\">;\n            position-area: block-end span-inline-start;\n            position-try: flip-block, flip-inline, flip-block flip-inline;\n            inset: unset;\n            margin: 0;\n          }\n        }\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n        <span class=\"hljs-attr\">commandfor<\/span>=<span class=\"hljs-string\">\"<\/span><\/span><\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.menuId}<\/span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"<\/span>\n        <span class=\"hljs-attr\">command<\/span>=<span class=\"hljs-string\">\"toggle-popover\"<\/span>\n      &gt;<\/span>\n        <\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.buttonName}<\/span><span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n    `<\/span>;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then usage is as simple as this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a-menu<\/span> <span class=\"hljs-attr\">button-name<\/span>=<span class=\"hljs-string\">\"My Menu\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">menu<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>&gt;<\/span>Edit<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>&gt;<\/span>Delete<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>&gt;<\/span>Share<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">menu<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a-menu<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Notice we <strong>don&#8217;t<\/strong> need to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Remember a unique ID on the menu.<\/li>\n\n\n\n<li>Remember the popover commands.<\/li>\n\n\n\n<li>Remember to attach an <code>anchor-name<\/code> or <code>position-anchor<\/code> to put the menu next to the button.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">&#8230; but now we have a problem.<\/h3>\n\n\n\n<p>Even though we&#8217;re putting a unique ID on the menu and using unique custom idents on the anchors, the <strong>first <\/strong>menu will open in the position of the <strong>last<\/strong> button. Why? Because we&#8217;re using the Light DOM here, and the last generic <code>a-menu menu {}<\/code> selector will <strong>override<em> <\/em><\/strong>the first one, making <strong>all<em> <\/em><\/strong>buttons\/menus use the values of the last one.<\/p>\n\n\n\n<details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>Problem Demo<\/summary>\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_019c679f-6fd0-738d-9cfe-83c9bdb1a0db\" src=\"\/\/codepen.io\/editor\/anon\/embed\/019c679f-6fd0-738d-9cfe-83c9bdb1a0db?height=450&amp;theme-id=1&amp;slug-hash=019c679f-6fd0-738d-9cfe-83c9bdb1a0db&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed 019c679f-6fd0-738d-9cfe-83c9bdb1a0db\" title=\"CodePen Embed 019c679f-6fd0-738d-9cfe-83c9bdb1a0db\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/details>\n\n\n\n<h2 class=\"wp-block-heading\">Using @scope<\/h2>\n\n\n\n<p>It occured to me that a potential fix here is the newfangled <code>@scope<\/code> in CSS. If we updated the style block to be this instead:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">@scope {\n  :scope {\n    <span class=\"hljs-attr\">display<\/span>: inline-block;\n    \n    button {\n      anchor-name: --menu-button-${<span class=\"hljs-keyword\">this<\/span>.menuId};\n    }\n\n    menu {\n      position-anchor: --menu-button-${<span class=\"hljs-keyword\">this<\/span>.menuId};\n      position-area: block-end span-inline-start;\n      position-<span class=\"hljs-keyword\">try<\/span>: flip-block, flip-inline, flip-block flip-inline;\n      inset: unset;\n      margin: <span class=\"hljs-number\">0<\/span>;\n      border: <span class=\"hljs-number\">0<\/span>;\n      padding: <span class=\"hljs-number\">0.5<\/span>rem;\n      background: light-dark(white, black);\n      border-radius: <span class=\"hljs-number\">4<\/span>px;\n      box-shadow: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">10<\/span>px <span class=\"hljs-number\">10<\/span>px lch(<span class=\"hljs-number\">0<\/span>% <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> \/ <span class=\"hljs-number\">0.2<\/span>);\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This fixes the problem because each <code>&lt;style><\/code> block only applies directly to the <code>&lt;a-menu><\/code> web component it lives inside of. <\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_019c67a9-219d-7113-aabb-67c2b6077617\" src=\"\/\/codepen.io\/editor\/anon\/embed\/019c67a9-219d-7113-aabb-67c2b6077617?height=450&amp;theme-id=1&amp;slug-hash=019c67a9-219d-7113-aabb-67c2b6077617&amp;default-tab=js,result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed 019c67a9-219d-7113-aabb-67c2b6077617\" title=\"CodePen Embed 019c67a9-219d-7113-aabb-67c2b6077617\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>Kind of a nice little use case for <code>@scope<\/code>. But&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using anchor-scope (instead)<\/h2>\n\n\n\n<p>It turns out there is an even cleaner fix for this, because anchor positioning actually has its own version of scoping just for it. It&#8217;s called <code><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/Reference\/Properties\/anchor-scope\">anchor-scope<\/a><\/code>. <\/p>\n\n\n\n<p>Rather than scoping everything, as well as requiring a unique custom ident for the anchor, we can tell the root web component to scope that custom ident to itself. Meaning that anything internally that is looking for that custom ident should look in this little neck-of-the-DOM-woods and no further.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-code-table\"><span class='shcb-loc'><span>a-menu {\n<\/span><\/span><mark class='shcb-loc'><span>  anchor-scope: --menu-button;\n<\/span><\/mark><span class='shcb-loc'><span>  display: inline-block;\n<\/span><\/span><span class='shcb-loc'><span>  \n<\/span><\/span><span class='shcb-loc'><span>  button {\n<\/span><\/span><mark class='shcb-loc'><span>    anchor-name: --menu-button;\n<\/span><\/mark><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  menu {\n<\/span><\/span><mark class='shcb-loc'><span>    position-anchor: --menu-button;\n<\/span><\/mark><span class='shcb-loc'><span>    position-area: block-end span-inline-start;\n<\/span><\/span><span class='shcb-loc'><span>    position-<span class=\"hljs-keyword\">try<\/span>: flip-block, flip-inline, flip-block flip-inline;\n<\/span><\/span><span class='shcb-loc'><span>    inset: <span class=\"hljs-keyword\">unset<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    margin: <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    border: <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    padding: <span class=\"hljs-number\">0.5<\/span>rem;\n<\/span><\/span><span class='shcb-loc'><span>    background: light-dark(white, black);\n<\/span><\/span><span class='shcb-loc'><span>    border-radius: <span class=\"hljs-number\">4<\/span>px;\n<\/span><\/span><span class='shcb-loc'><span>    box-shadow: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">10<\/span>px <span class=\"hljs-number\">10<\/span>px lch(<span class=\"hljs-number\">0<\/span>% <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> \/ <span class=\"hljs-number\">0.2<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>&lt;\/style&gt;\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now it doesn&#8217;t matter if multiple elements are all using the same custom ident for an anchor because they are all scoped to their own parents.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_019c67ae-32c8-773d-9159-d36a67b04ff1\" src=\"\/\/codepen.io\/editor\/anon\/embed\/019c67ae-32c8-773d-9159-d36a67b04ff1?height=450&amp;theme-id=1&amp;slug-hash=019c67ae-32c8-773d-9159-d36a67b04ff1&amp;default-tab=js,result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed 019c67ae-32c8-773d-9159-d36a67b04ff1\" title=\"CodePen Embed 019c67ae-32c8-773d-9159-d36a67b04ff1\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Bonus: Implied Anchors<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.matuzo.at\/blog\/2026\/better-defaults-for-popovers\">I learned <em>another<\/em> thing<\/a> recently that helps just a smidge here too. That <code>position-anchor<\/code> we&#8217;re putting on the menu? It&#8217;s simply not needed. Because our <code>&lt;button><\/code> opens our <code>&lt;menu><\/code> with those popover commands, which match the <code>id<\/code> and <code>commandfor<\/code>, the <code>&lt;menu><\/code> has an &#8220;implied anchor&#8221; of the <code>&lt;button><\/code>. That&#8217;s amazing to me. You don&#8217;t normally see it because popovers have <code>margin: auto;<\/code> on them in the UA stylesheet which centers them on the screen and kinda overrides the anchor. But as soon as that is removed, like we&#8217;re doing with <code>margin: 0;<\/code>, it &#8220;just works&#8221;. <\/p>\n\n\n\n<p> <a href=\"https:\/\/codepen.io\/editor\/chriscoyier\/pen\/019c67b2-f490-711e-afb2-c5df5b466edc\">Demo<\/a><\/p>\n\n\n\n<p>I&#8217;m totally adding <a href=\"https:\/\/www.matuzo.at\/blog\/2026\/better-defaults-for-popovers\">this<\/a> to <a href=\"https:\/\/frontendmasters.com\/blog\/the-coyier-css-starter\/\">my reset stylesheet<\/a>. (And I like how Manuel is down with the perfect fallbacks for anchors, <code>position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;<\/code>, which <a href=\"https:\/\/frontendmasters.com\/blog\/popover-context-menus-with-anchor-positioning\/#the-most-useful-position-try-incantation\">we also came to here.<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Again, this isn&#8217;t a smart web component to actually use because we&#8217;ve moved a very nice HTML\/CSS only feature into requiring JavaScript. But hey, we learned some stuff along the way. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Turns out `anchor-scope` is pretty darn useful for button\/menu setups that will appear multiple times on the same page.<\/p>\n","protected":false},"author":1,"featured_media":8612,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[452,7,31,3,120,36],"class_list":["post-8550","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-anchor-scope","tag-css","tag-html","tag-javascript","tag-popover","tag-web-components"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2026\/02\/menu.jpg?fit=2100%2C1500&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/8550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=8550"}],"version-history":[{"count":6,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/8550\/revisions"}],"predecessor-version":[{"id":8613,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/8550\/revisions\/8613"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/8612"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=8550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=8550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=8550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}