{"id":2743,"date":"2024-06-19T05:41:27","date_gmt":"2024-06-19T11:41:27","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=2743"},"modified":"2024-06-24T13:55:41","modified_gmt":"2024-06-24T19:55:41","slug":"footnotes-progressively-enhanced-to-popovers","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/footnotes-progressively-enhanced-to-popovers\/","title":{"rendered":"Footnotes Progressively Enhanced to Popovers"},"content":{"rendered":"\n<p>Michelle Barker is onto an excellent idea in <a href=\"https:\/\/css-irl.info\/progressively-enhanced-popover-toggletips\/\">Progressively Enhanced Popover Toggletips<\/a>. Her idea is that footnotes are the perfect sort of thing to make popovers. You know popovers: It&#8217;s like when I put a superset<sup data-fn=\"cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1\" class=\"fn\"><a href=\"#cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1\" id=\"cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1-link\">1<\/a><\/sup> number in a sentence (like I just did) and then link it down to the bottom of the post to explain something in more detail which would have been distracting detail to put in the paragraph itself. But &#8220;jumping down&#8221; like <code>&lt;a href=\"#footnote-1\"&gt;<\/code> is <em>also<\/em> distracting. Why not just open the extra information in a little popup? Indeed!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"846\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?resize=1024%2C846&#038;ssl=1\" alt=\"\" class=\"wp-image-2765\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?resize=1024%2C846&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?resize=300%2C248&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?resize=768%2C634&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?resize=1536%2C1269&amp;ssl=1 1536w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/CleanShot-2024-06-19-at-07.32.53%402x.png?w=1564&amp;ssl=1 1564w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>I like the idea of &#8220;doing both&#8221;. As Michelle says:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>We&nbsp;<em>could<\/em>&nbsp;also hide the list when anchor positioning is supported, but I think it\u2019s also more user-friendly to include references as a list&nbsp;<strong>in addition<\/strong>&nbsp;to within the document.<\/p>\n<\/blockquote>\n\n\n\n<p>But then I read:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>A small downside is that this approach requires a bit of content duplication.<\/p>\n<\/blockquote>\n\n\n\n<p>The way Michelle did it was to put an <code>&lt;ol&gt;<\/code> of footnotes at the bottom as usual, and then also put the <code>[popover]<\/code> footnotes up in the content as well, which is the duplication. <\/p>\n\n\n\n<p>The duplication isn&#8217;t <em>that<\/em> big of a deal. It just could be a little annoying for some readers (<em>uh, yes, I already read this thank you<\/em>). It mostly sucks because it makes them harder to maintain. You&#8217;d have to make identical changes manually in two places. If that&#8217;s no problem, Michelle&#8217;s technique is sound and you could use it as-is!<\/p>\n\n\n\n<p>But&#8230; it got me thinking that there must be a way to re-use the same content for both!<\/p>\n\n\n<div class=\"box article-series\">\n  <header>\n    <h3 class=\"article-series-header\">Article Series<\/h3>\n  <\/header>\n  <div class=\"box-content\">\n            <ol>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/using-the-popover-api-for-html-tooltips\/\">Using the Popover API for HTML Tooltips<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/footnotes-progressively-enhanced-to-popovers\/\">Footnotes Progressively Enhanced to Popovers<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/popovers-work-pretty-nicely-as-slide-out-drawers\/\">Popovers Work Pretty Nicely as Slide-Out Drawers<\/a>\n            <\/li>\n                  <\/ol>\n        <\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Attempt 1) Duplicates via JavaScript<\/h2>\n\n\n\n<p>My first take was that we gotta stop the manual content duplication. That&#8217;ll be a huge pain to maintain. So let&#8217;s do the duplication of the footnote list in JavaScript, hide it both visually and from screen readers as the original list is still there, and use the duplicates for the popovers. <\/p>\n\n\n\n<p>Since that original list is still there, we can test the browser support for popovers and just entirely bail out if the support isn&#8217;t there.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ browser supports popovers<\/span>\n<span class=\"hljs-keyword\">if<\/span> (HTMLElement.prototype.hasOwnProperty(<span class=\"hljs-string\">\"popover\"<\/span>)) {\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><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 we&#8217;ll:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Clone the existing list of footnotes<\/li>\n\n\n\n<li>Adjust the IDs so we don&#8217;t have duplicate IDs<\/li>\n\n\n\n<li>Add the <code>popover<\/code> attributes<\/li>\n<\/ol>\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\">if<\/span> (HTMLElement.prototype.hasOwnProperty(<span class=\"hljs-string\">\"popover\"<\/span>)) {\n  <span class=\"hljs-comment\">\/\/ find the list of footnotes and clone it<\/span>\n  <span class=\"hljs-keyword\">const<\/span> references = <span class=\"hljs-built_in\">document<\/span>.querySelector(<span class=\"hljs-string\">\".references\"<\/span>);\n  <span class=\"hljs-keyword\">const<\/span> duplicateReferences = references.cloneNode(<span class=\"hljs-literal\">true<\/span>);\n  \n  <span class=\"hljs-comment\">\/\/ hide the duplicate from screen readers before re-injecting it into DOM<\/span>\n  duplicateReferences.setAttribute(<span class=\"hljs-string\">\"aria-hidden\"<\/span>, <span class=\"hljs-literal\">true<\/span>);\n  references.parentNode.insertBefore(duplicateReferences, references.nextSibling);\n\t\n  <span class=\"hljs-comment\">\/\/ loop over each footnote to make a popover<\/span>\n  <span class=\"hljs-keyword\">const<\/span> popovers = duplicateReferences.querySelectorAll(<span class=\"hljs-string\">\"li\"<\/span>);\n  popovers.forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">popover<\/span> =&gt;<\/span> {\n    popover.id = <span class=\"hljs-string\">`ref_<span class=\"hljs-subst\">${popover.id}<\/span>`<\/span>;\n    popover.setAttribute(<span class=\"hljs-string\">\"popover\"<\/span>, <span class=\"hljs-literal\">true<\/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>Looking in the web inspector we can see now that both lists are there:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"866\" height=\"242\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/Screenshot-2024-06-19-at-6.34.54%E2%80%AFAM.png?resize=866%2C242&#038;ssl=1\" alt=\"\" class=\"wp-image-2763\" style=\"width:501px;height:auto\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/Screenshot-2024-06-19-at-6.34.54%E2%80%AFAM.png?w=866&amp;ssl=1 866w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/Screenshot-2024-06-19-at-6.34.54%E2%80%AFAM.png?resize=300%2C84&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/06\/Screenshot-2024-06-19-at-6.34.54%E2%80%AFAM.png?resize=768%2C215&amp;ssl=1 768w\" sizes=\"auto, (max-width: 866px) 100vw, 866px\" \/><\/figure>\n<\/div>\n\n\n<p>The <code>&lt;button&gt;<\/code> elements which trigger the popups are still up above in the content, referring to these new popovers that now exist. In fact both the link and the button are both there:<\/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<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"popover-replace\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"#1\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">sup<\/span>&gt;<\/span>1<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">sup<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">popovertarget<\/span>=<span class=\"hljs-string\">\"ref_1\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">sup<\/span>&gt;<\/span>1<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">sup<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/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><strong>People will only ever see\/use one or the other.<\/strong> There is an <code>&lt;a&gt;<\/code> link there by default, then if popovers are supported, it&#8217;s replaced by the button. That was already in Michelle&#8217;s code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-attr\">&#91;popovertarget]<\/span> {\n  <span class=\"hljs-attribute\">display<\/span>: none;\n}\n\n<span class=\"hljs-keyword\">@supports<\/span> (<span class=\"hljs-attribute\">anchor-name:<\/span> --ref_1) {\n  <span class=\"hljs-selector-attr\">&#91;popovertarget]<\/span> {\n    <span class=\"hljs-attribute\">display<\/span>: inline;\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\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>So that&#8217;s this!<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_PovOemv\" src=\"\/\/codepen.io\/anon\/embed\/PovOemv?height=450&amp;theme-id=47434&amp;slug-hash=PovOemv&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed PovOemv\" title=\"CodePen Embed PovOemv\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Attempt 2) The Original List can be Popovers Too<\/h2>\n\n\n\n<p>That previous attempt required JavaScript, which doesn&#8217;t bother me really as it&#8217;s progressive enhancement, but it&#8217;s not always clear where JavaScript like that that spreads across different areas of a page would go, and may be a bit more fragile. <\/p>\n\n\n\n<p>Can&#8217;t the footnotes at the bottom of the page&#8230; just be the popovers themselves? They can! Mostly!<\/p>\n\n\n\n<p>The first trouble is that adding the <code>popover<\/code> attribute immediately makes them hidden. So the trick is to un-hide them and style them as you want them <em>as a list<\/em>. Then when they are open, which we know with the <code>:popover-open<\/code> pseudo-class, we can style them like popovers. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-comment\">\/* closed *\/<\/span>\n<span class=\"hljs-selector-attr\">&#91;popover]<\/span> {\n  <span class=\"hljs-attribute\">display<\/span>: list-item;\n  <span class=\"hljs-attribute\">position<\/span>: relative;\n  <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-attribute\">width<\/span>: auto;\n  <span class=\"hljs-attribute\">overflow<\/span>: visible;\n\n  <span class=\"hljs-comment\">\/* open *\/<\/span>\n  &amp;:popover-open {\n    <span class=\"hljs-attribute\">display<\/span>: block;\n    <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n    <span class=\"hljs-attribute\">background<\/span>: lavender;\n    <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">0.5rem<\/span>;\n    <span class=\"hljs-attribute\">max-width<\/span>: <span class=\"hljs-number\">15rem<\/span>;\n    ...\n   }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The first side-effect here is that when any of these popovers are open, the footnote in the list below disappears. The content literally transports to the new popover location. So that causes a bit of reflow and you might not like it for that reason alone. But it works!<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_rNgJrjo\" src=\"\/\/codepen.io\/anon\/embed\/rNgJrjo?height=450&amp;theme-id=47434&amp;slug-hash=rNgJrjo&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed rNgJrjo\" title=\"CodePen Embed rNgJrjo\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>There is a second side-effect here. The list of footnotes-become-popovers are forced to be <code>display: list-item<\/code> so they are visible and have numbers and such. If you leave them as that when you move them into popover position, the little number marker will come with it. You can hide it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-attr\">&#91;popover]<\/span> {\n  &amp;:popover-open {\n    &amp;::marker {\n      <span class=\"hljs-attribute\">content<\/span>: <span class=\"hljs-string\">\"\"<\/span>;\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you make the popover, say, <code>display: block<\/code> instead, this immediately breaks the automatic list numbering. You&#8217;ll need to bring your own list numbering that is based on counters instead.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.references<\/span> {\n  <span class=\"hljs-attribute\">counter-reset<\/span>: item;\n  &gt; li {\n    <span class=\"hljs-attribute\">counter-increment<\/span>: item;\n    &amp;::marker {\n      <span class=\"hljs-attribute\">content<\/span>: <span class=\"hljs-built_in\">counter<\/span>(item) <span class=\"hljs-string\">\") \"<\/span>;\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Others?<\/h2>\n\n\n\n<p>There are upsides and downsides to both of the above techniques. Mostly they focus on solving content duplication. <\/p>\n\n\n\n<p>There is another thing they fail at though. Michelle notes:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>I\u2019m making use of the&nbsp;<code>:has<\/code>&nbsp;pseudo-class to position the little arrows attached to the bubbles when the popover is open, by styling the&nbsp;<code>::before<\/code>&nbsp;pseudo-element of the button.<\/p>\n<\/blockquote>\n\n\n\n<p>My two techniques fail at having the little arrow be present because the DOM position of the button with target and popover aren&#8217;t next to each other anymore. You might imagine the little pointer off the popover bubble being part of the bubble itself, but no, Michelle cleverly made it part of the button instead, <strong>so it&#8217;s always pointing at the correct place<\/strong>. I love that. <\/p>\n\n\n\n<p>If you wanted to preserve that, you could write JavaScript that duplicates the footnote popovers like I did in the <em>first<\/em> example, but then place them <em>within the content<\/em> (likely with <code>aria-hidden<\/code> to avoid duplicate content awkwardness) like in Michelle&#8217;s original demo. <\/p>\n\n\n\n<p>I&#8217;ll leave that as an excercise for you readers if you wish to take it on. I&#8217;d love to see it, or any other interesting variations.<\/p>\n\n\n<div class=\"box article-series\">\n  <header>\n    <h3 class=\"article-series-header\">Article Series<\/h3>\n  <\/header>\n  <div class=\"box-content\">\n            <ol>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/using-the-popover-api-for-html-tooltips\/\">Using the Popover API for HTML Tooltips<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/footnotes-progressively-enhanced-to-popovers\/\">Footnotes Progressively Enhanced to Popovers<\/a>\n            <\/li>\n                      <li>\n              <a href=\"https:\/\/frontendmasters.com\/blog\/popovers-work-pretty-nicely-as-slide-out-drawers\/\">Popovers Work Pretty Nicely as Slide-Out Drawers<\/a>\n            <\/li>\n                  <\/ol>\n        <\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<ol class=\"wp-block-footnotes\"><li id=\"cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1\">My favorite part about footnotes is the perfect excuse to use the <code>&lt;sup><\/code> element. <a href=\"#cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1-link\" aria-label=\"Jump to footnote reference 1\">\u21a9\ufe0e<\/a><\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>Michelle Barker&#8217;s technique for popover footnotes is great. Here we look at ways we could fight the content duplication. There are ups and downs. <\/p>\n","protected":false},"author":1,"featured_media":1975,"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":"[{\"content\":\"My favorite part about footnotes is the perfect excuse to use the <code>&lt;sup><\/code> element.\",\"id\":\"cd7b00ca-447a-4fb2-aff5-84e0c6c5cea1\"}]"},"categories":[1],"tags":[7,31,3,120],"class_list":["post-2743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-css","tag-html","tag-javascript","tag-popover"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/popup-thumb.jpg?fit=1000%2C500&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2743","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=2743"}],"version-history":[{"count":10,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2743\/revisions"}],"predecessor-version":[{"id":2827,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2743\/revisions\/2827"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/1975"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=2743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=2743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=2743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}