{"id":1511,"date":"2024-04-02T12:02:50","date_gmt":"2024-04-02T18:02:50","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=1511"},"modified":"2024-04-03T09:52:35","modified_gmt":"2024-04-03T15:52:35","slug":"drawing-a-line-to-connect-elements-with-css-anchor-positioning","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/drawing-a-line-to-connect-elements-with-css-anchor-positioning\/","title":{"rendered":"Drawing a Line to Connect Elements with CSS Anchor Positioning"},"content":{"rendered":"\n<p>The World Wide Web Consortium (W3C) <a href=\"https:\/\/www.w3.org\/news\/2023\/first-public-working-draft-css-anchor-positioning\/\" target=\"_blank\" rel=\"noreferrer noopener\">published a First Public Working Draft of CSS Anchor Positioning<\/a> last year, so I thought I would give it a try. I already had a perfect candidate to try it on: a component on my other site, <a href=\"https:\/\/adedicated.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">adedicated.dev<\/a>, which showcase my services by linking different words together.<\/p>\n\n\n\n\t\t<figure class=\"wp-block-jetpack-videopress jetpack-videopress-player\" style=\"\" >\n\t\t\t<div class=\"jetpack-videopress-player__wrapper\"> <iframe title=\"VideoPress Video Player\" aria-label='VideoPress Video Player' width='500' height='181' src='https:\/\/videopress.com\/embed\/IW3WdUJU?cover=1&amp;autoPlay=0&amp;controls=1&amp;loop=0&amp;muted=0&amp;persistVolume=1&amp;playsinline=0&amp;preloadContent=metadata&amp;useAverageColor=1&amp;hd=0' frameborder='0' allowfullscreen data-resize-to-parent=\"true\" allow='clipboard-write'><\/iframe><script src='https:\/\/v0.wordpress.com\/js\/next\/videopress-iframe.js?m=1674852142'><\/script><\/div>\n\t\t\t\n\t\t\t\n\t\t<\/figure>\n\t\t\n\n\n<p>To link different elements in columns, my component relies on heavy JavaScript calculation. <a href=\"https:\/\/codepen.io\/CiTA\/pen\/OJapmPG\" target=\"_blank\" rel=\"noreferrer noopener\">Here\u2019s that example.<\/a> While I love solving a math problem here and there, I prefer browsers doing these kinds of calculations for me!<\/p>\n\n\n\n<p>Let\u2019s take a look at CSS Anchor Positioning and see how it might have a solution for us.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Bit about CSS Anchor Positioning<\/h2>\n\n\n\n<p><a target=\"_blank\" href=\"https:\/\/frontendmasters.com\/blog\/what-you-need-to-know-about-modern-css-spring-2024-edition\/#toc-35\" rel=\"noreferrer noopener\">CSS Anchor Positioning<\/a> provides a better way to position an element in relation to another element. Think of a tooltip and how it is positioned related to the element that triggers it. The <em>perfect<\/em> tooltip usually \u201cknows\u201d if it overflows outside of the containing block. For example, if the tooltip doesn\u2019t fit <em>above<\/em> its trigger element, it should go <em>below<\/em> it. CSS Anchor Positioning solves this problem for us, and that mean less JavaScript calculation.<\/p>\n\n\n\n<p class=\"learn-more\">It is worth noting that CSS Anchor Positioning is quite new API and it is prone to changes. At the time of this writing, the only browser that supports this feature is Chrome Canary, and it is behind the \u201cExperimental Web Platform Features\u201d flag.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Demo<\/h2>\n\n\n\n<p>Back to my component. I have a three columns, and in each one I have a set of words which, when linked, form a new term. When you hover over any word, a random word in three different columns is highlighted and the final term is created. For example, \u201cCreating WordPress Websites\u201d or \u201cDeveloping HubSpot Pages\u201d or \u201cUpdating Shopify Layouts\u201d. I thought it would be fun to showcase my skills in such a way. Here\u2019s how the component works:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_rNQzyyQ\" src=\"\/\/codepen.io\/anon\/embed\/rNQzyyQ?height=450&amp;theme-id=47434&amp;slug-hash=rNQzyyQ&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed rNQzyyQ\" title=\"CodePen Embed rNQzyyQ\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>To solve the problem of linking different words, we need to prepare the HTML for that. I am using two <code>&lt;div&gt;<\/code>s for two links, first one for link between first and second column, and the other one for linking second and third column.<\/p>\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\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"link link--alpha\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"link link--beta\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/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>First thing we need to do is to position our <code>&lt;div&gt;<\/code>s. For each level links, I had to set up the <code>min-block-size<\/code> (the <a href=\"https:\/\/frontendmasters.com\/blog\/what-you-need-to-know-about-modern-css-spring-2024-edition\/#logical-properties\" target=\"_blank\" rel=\"noreferrer noopener\">logical equivalent<\/a> of width in a left-to-right or right-to-left language \u2014 we\u2019ll be using more of these logical properties as this article goes on):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.link<\/span> {\n  <span class=\"hljs-attribute\">position<\/span>: absolute;\n  <span class=\"hljs-attribute\">min-block-size<\/span>: <span class=\"hljs-number\">2px<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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>Then we need a grid of all words. I am using unordered list and CSS Grid to achieve 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\">ul<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Creating<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>WordPress<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Websites<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Developing<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>HubSpot<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Pages<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Updating<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Shopify<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Layouts<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Implementing<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Jekyll<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Templates<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Optimizing<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Hugo<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span>&gt;<\/span>Components<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/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<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-pseudo\">:root<\/span> {\n  <span class=\"hljs-attribute\">--color-alpha<\/span>: lightcyan;\n  <span class=\"hljs-attribute\">--color-beta<\/span>: cyan;\n  <span class=\"hljs-attribute\">--color-gamma<\/span>: indigo;\n}\n\n<span class=\"hljs-selector-tag\">ul<\/span> {\n  <span class=\"hljs-attribute\">list-style<\/span>: none;\n  <span class=\"hljs-attribute\">display<\/span>: grid;\n  <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-built_in\">repeat<\/span>(<span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">1<\/span>fr);\n  <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">32px<\/span>;\n  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n}\n\n<span class=\"hljs-selector-tag\">li<\/span> {\n  <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-gamma);\n  <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-alpha);\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-built_in\">var<\/span>(--space-alpha);\n  <span class=\"hljs-attribute\">position<\/span>: relative;\n  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">32px<\/span>;\n  <span class=\"hljs-attribute\">transition<\/span>: background-color <span class=\"hljs-number\">110ms<\/span>, color <span class=\"hljs-number\">110ms<\/span>;\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>To highlight the word, I am using data attributes on unordered list element, like so:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" 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\">ul<\/span> <span class=\"hljs-attr\">data-col1<\/span>=<span class=\"hljs-string\">\"2\"<\/span> <span class=\"hljs-attr\">data-col2<\/span>=<span class=\"hljs-string\">\"3\"<\/span> <span class=\"hljs-attr\">data-col3<\/span>=<span class=\"hljs-string\">\"4\"<\/span>&gt;<\/span>\n  ...\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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<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\">\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(1)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(4)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(7)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(10)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(13)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(2)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(5)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(8)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(11)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(14)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(3)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(6)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(9)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(12)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(15)<\/span> {\n  <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--color-beta);\n  <span class=\"hljs-attribute\">transition<\/span>: background-color <span class=\"hljs-built_in\">var<\/span>(--trd-beta), color <span class=\"hljs-built_in\">var<\/span>(--trd-beta);\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>Now for the fun stuff \u2014 let\u2019s anchor some elements! We are going to define three anchor-names, each for a single column. These elements will be defined by the word element. That way our line elements will be able to use the position of linked word elements and link each other.<\/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-attr\">&#91;data-col1=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(1)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(4)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(7)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(10)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col1=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(13)<\/span> {\n  <span class=\"hljs-attribute\">anchor-name<\/span>: --link-col1;\n}\n\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(2)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(5)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(8)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(11)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col2=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(14)<\/span> {\n  <span class=\"hljs-attribute\">anchor-name<\/span>: --link-col2;\n}\n\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"1\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(3)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"2\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(6)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"3\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(9)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"4\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(12)<\/span>,\n<span class=\"hljs-selector-attr\">&#91;data-col3=<span class=\"hljs-string\">\"5\"<\/span>]<\/span> <span class=\"hljs-selector-tag\">li<\/span><span class=\"hljs-selector-pseudo\">:nth-child(15)<\/span> {\n  <span class=\"hljs-attribute\">anchor-name<\/span>: --link-col3;\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<p>Here\u2019s the image so you can visualize the link elements more easily.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"496\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688556691412_image.png?resize=1024%2C496&#038;ssl=1\" alt=\"\" class=\"wp-image-1521\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688556691412_image.png?resize=1024%2C496&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688556691412_image.png?resize=300%2C145&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688556691412_image.png?resize=768%2C372&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688556691412_image.png?w=1452&amp;ssl=1 1452w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>Next, we need to define the offset for our element by using the anchor function. We want our first line (the left pink rectangle) to start outside and in the middle of the first word element and to end outside and in the middle of the second word element.&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.link--alpha<\/span> {\n  <span class=\"hljs-attribute\">inset-block-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col1 center);\n  <span class=\"hljs-attribute\">inset-inline-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col1 right);\n  <span class=\"hljs-attribute\">inset-inline-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 left);\n  <span class=\"hljs-attribute\">inset-block-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 center);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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><em>(Editor&#8217;s note: I drew this crude diagram that follows to demonstrate how the placement of that pink rectangle works because it&#8217;s totally fascinating to me!)<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"851\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/Frame-3.png?resize=1024%2C851&#038;ssl=1\" alt=\"\" class=\"wp-image-1528\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/Frame-3.png?resize=1024%2C851&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/Frame-3.png?resize=300%2C249&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/Frame-3.png?resize=768%2C638&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/Frame-3.png?w=1452&amp;ssl=1 1452w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>It&#8217;s the same setup for the second line, but we are the referencing the second and third word elements instead of the first and second.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.link--beta<\/span> {\n  <span class=\"hljs-attribute\">inset-block-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 center);\n  <span class=\"hljs-attribute\">inset-inline-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 right);\n  <span class=\"hljs-attribute\">inset-inline-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col3 left);\n  <span class=\"hljs-attribute\">inset-block-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col3 center);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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>To make the lines, I am using a linear gradient in the following fashion:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The first linear gradient is vertical line that is 100% in height and placed in the center of rectangle<\/li>\n\n\n\n<li>The second linear gradient is horizontal line that starts in the top left corner and is 50% of width<\/li>\n\n\n\n<li>The third linear gradient is horizontal line that starts in the bottom right corner and is 50% of width<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.link<\/span> {\n  <span class=\"hljs-attribute\">background-image<\/span>: <span class=\"hljs-built_in\">linear-gradient<\/span>(to bottom, black, black), <span class=\"hljs-built_in\">linear-gradient<\/span>(to right, black, black), <span class=\"hljs-built_in\">linear-gradient<\/span>(to bottom, black, black);\n  <span class=\"hljs-attribute\">background-size<\/span>: <span class=\"hljs-number\">2px<\/span>, <span class=\"hljs-number\">50%<\/span> <span class=\"hljs-number\">2px<\/span>, <span class=\"hljs-number\">50%<\/span> <span class=\"hljs-number\">2px<\/span>;\n  <span class=\"hljs-attribute\">background-position<\/span>: center, top left, bottom right;\n  <span class=\"hljs-attribute\">background-repeat<\/span>: no-repeat;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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>Here\u2019s how it looks now.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"498\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688557469983_image.png?resize=1024%2C498&#038;ssl=1\" alt=\"\" class=\"wp-image-1522\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688557469983_image.png?resize=1024%2C498&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688557469983_image.png?resize=300%2C146&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688557469983_image.png?resize=768%2C373&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/s_9BD8428021A09E894E5A4674E74F0976CA4B4306AA597E2DA76B21FE591ADAF6_1688557469983_image.png?w=1448&amp;ssl=1 1448w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>To generate different terms on each hover event and to automatically change the terms when no hover effects occur to make the whole component more appealing and inviting, we need to introduce a bit of JavaScript. Once the timeout expires, JavaScript will update the <code>data-col1<\/code>, <code>data-col2<\/code>, and <code>data-col3<\/code> attributes.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> highlighter = <span class=\"hljs-function\">(<span class=\"hljs-params\">timeout = <span class=\"hljs-number\">4000<\/span><\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> $ul = <span class=\"hljs-built_in\">document<\/span>.querySelector(<span class=\"hljs-string\">'ul'<\/span>)\n   \n  <span class=\"hljs-keyword\">const<\/span> getRandomNumber = <span class=\"hljs-function\">(<span class=\"hljs-params\">min, max<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">Math<\/span>.floor(<span class=\"hljs-built_in\">Math<\/span>.random() * (max - min + <span class=\"hljs-number\">1<\/span>)) + min;\n  }\n  \n  <span class=\"hljs-keyword\">const<\/span> randomHighlighter = <span class=\"hljs-function\">(<span class=\"hljs-params\">$s, c<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> nth1 = &#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">7<\/span>, <span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">13<\/span>]\n    <span class=\"hljs-keyword\">const<\/span> nth2 = &#91;<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">8<\/span>, <span class=\"hljs-number\">11<\/span>, <span class=\"hljs-number\">14<\/span>]\n    <span class=\"hljs-keyword\">const<\/span> nth3 = &#91;<span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">6<\/span>, <span class=\"hljs-number\">9<\/span>, <span class=\"hljs-number\">12<\/span>, <span class=\"hljs-number\">15<\/span>]\n    \n    <span class=\"hljs-keyword\">let<\/span> c1 = getRandomNumber(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">5<\/span>)\n    <span class=\"hljs-keyword\">let<\/span> c2 = getRandomNumber(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">5<\/span>)\n    <span class=\"hljs-keyword\">let<\/span> c3 = getRandomNumber(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">5<\/span>)\n\n    <span class=\"hljs-keyword\">if<\/span>(c &amp;&amp; nth1.indexOf(c) !== <span class=\"hljs-number\">-1<\/span>) {\n      c1 = nth1.indexOf(c) + <span class=\"hljs-number\">1<\/span>\n    }\n\n    <span class=\"hljs-keyword\">if<\/span>(c &amp;&amp; nth2.indexOf(c) !== <span class=\"hljs-number\">-1<\/span>) {\n      c2 = nth2.indexOf(c) + <span class=\"hljs-number\">1<\/span>\n    }\n\n    <span class=\"hljs-keyword\">if<\/span>(c &amp;&amp; nth3.indexOf(c) !== <span class=\"hljs-number\">-1<\/span>) {\n      c3 = nth3.indexOf(c) + <span class=\"hljs-number\">1<\/span>\n    }\n\n    <span class=\"hljs-keyword\">if<\/span>(c2 &lt; c1) {\n      <span class=\"hljs-built_in\">document<\/span>.body.classList.add(<span class=\"hljs-string\">'link-alpha-inverse'<\/span>)\n    } <span class=\"hljs-keyword\">else<\/span> {\n      <span class=\"hljs-built_in\">document<\/span>.body.classList.remove(<span class=\"hljs-string\">'link-alpha-inverse'<\/span>)\n    }\n    \n    <span class=\"hljs-keyword\">if<\/span>(c3 &lt; c2) {\n      <span class=\"hljs-built_in\">document<\/span>.body.classList.add(<span class=\"hljs-string\">'link-beta-inverse'<\/span>)\n    } <span class=\"hljs-keyword\">else<\/span> {\n      <span class=\"hljs-built_in\">document<\/span>.body.classList.remove(<span class=\"hljs-string\">'link-beta-inverse'<\/span>)\n    }\n\n    $s.setAttribute(<span class=\"hljs-string\">'data-col1'<\/span>, c1)\n    $s.setAttribute(<span class=\"hljs-string\">'data-col2'<\/span>, c2)\n    $s.setAttribute(<span class=\"hljs-string\">'data-col3'<\/span>, c3)\n  }\n\n  <span class=\"hljs-keyword\">if<\/span>($ul) {\n    <span class=\"hljs-keyword\">const<\/span> $lis = $ul.querySelectorAll(<span class=\"hljs-string\">'li'<\/span>)\n\n    <span class=\"hljs-keyword\">let<\/span> hover = <span class=\"hljs-literal\">false<\/span>;\n\n    randomHighlighter($ul)\n\n    <span class=\"hljs-keyword\">const<\/span> si = setInterval(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">if<\/span>(!hover) {\n        randomHighlighter($ul)\n      }\n    }, timeout)\n\n    $lis.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">$li, i<\/span>) =&gt;<\/span> {\n      $li.addEventListener(<span class=\"hljs-string\">'mouseenter'<\/span>, () =&gt; {\n        randomHighlighter($ul, i + <span class=\"hljs-number\">1<\/span>)\n\n        hover = <span class=\"hljs-literal\">true<\/span>\n      })\n      \n      $li.addEventListener(<span class=\"hljs-string\">'click'<\/span>, () =&gt; {\n        randomHighlighter($ul, i + <span class=\"hljs-number\">1<\/span>)\n\n        hover = <span class=\"hljs-literal\">true<\/span>\n      })\n    })\n\n    $ul.addEventListener(<span class=\"hljs-string\">'mouseleave'<\/span>, () =&gt; {\n      hover = <span class=\"hljs-literal\">false<\/span>\n    })\n  }\n}\n\nhighlighter()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><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>There is one final problem that we need to resolve. In case when the second word is \u201chigher\u201d than the first word, the positioning will not work. That is because we cannot have \u201cnegative\u201d elements, meaning the block end must be bigger or equal to block start property. To solve that problem, we will add another class to the body element.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ ...<\/span>\n\n<span class=\"hljs-keyword\">if<\/span>(c2 &lt; c1) {\n  <span class=\"hljs-built_in\">document<\/span>.body.classList.add(<span class=\"hljs-string\">'link-alpha-inverse'<\/span>)\n} <span class=\"hljs-keyword\">else<\/span> {\n  <span class=\"hljs-built_in\">document<\/span>.body.classList.remove(<span class=\"hljs-string\">'link-alpha-inverse'<\/span>)\n}\n\n<span class=\"hljs-keyword\">if<\/span>(c3 &lt; c2) {\n  <span class=\"hljs-built_in\">document<\/span>.body.classList.add(<span class=\"hljs-string\">'link-beta-inverse'<\/span>)\n} <span class=\"hljs-keyword\">else<\/span> {\n  <span class=\"hljs-built_in\">document<\/span>.body.classList.remove(<span class=\"hljs-string\">'link-beta-inverse'<\/span>)\n}\n\n<span class=\"hljs-comment\">\/\/ ...<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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>Now we could adjust our line component\u2019s CSS and fix the background positioning, too.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.link-alpha-inverse<\/span> <span class=\"hljs-selector-class\">.link--alpha<\/span> {\n  <span class=\"hljs-attribute\">inset-block-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col1 center);\n  <span class=\"hljs-attribute\">inset-block-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 center);\n  <span class=\"hljs-attribute\">background-position<\/span>: center, bottom left, top right;\n}\n\n<span class=\"hljs-selector-class\">.link-beta-inverse<\/span> <span class=\"hljs-selector-class\">.link--beta<\/span> {\n  <span class=\"hljs-attribute\">inset-block-end<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col2 center);\n  <span class=\"hljs-attribute\">inset-block-start<\/span>: <span class=\"hljs-built_in\">anchor<\/span>(--link-col3 center);\n  <span class=\"hljs-attribute\">background-position<\/span>: center, bottom left, top right;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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\">Conclusion<\/h2>\n\n\n\n<p>The original solution to this kind of problems required a whole lot of JavaScript calculations and clumsy inserting of <code>&lt;style&gt;<\/code> element to our HTML. With CSS Anchor Positioning, we use JavaScript only to update our data attributes and toggle body classes &#8211; all calculations and heavy lifting are done by our browser. I think that is wild and I cannot wait to see other useful places where this could be used.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final Demo<\/h2>\n\n\n\n<p>Remember to see the lines, at the time of publication, you need to be in Chrome Canary with the Experimental Web Features flag turned on. If you want to see more JavaScript calculation heavy fallback, <a href=\"https:\/\/codepen.io\/CiTA\/pen\/OJapmPG\">see here<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_abxEZwR\" src=\"\/\/codepen.io\/anon\/embed\/abxEZwR?height=450&amp;theme-id=47434&amp;slug-hash=abxEZwR&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed abxEZwR\" title=\"CodePen Embed abxEZwR\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>If you&#8217;re really into these ideas, definitely check out the web.dev article <a href=\"https:\/\/developer.chrome.com\/blog\/tether-elements-to-each-other-with-css-anchor-positioning\/#using_anchor_positioning\">Tether elements to each other with CSS anchor positioning<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The World Wide Web Consortium (W3C) published a First Public Working Draft of CSS Anchor Positioning last year, so I thought I would give it a try. I already had a perfect candidate to try it on: a component on my other site, adedicated.dev, which showcase my services by linking different words together. To link [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":1526,"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":[121,7],"class_list":["post-1511","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-anchor","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/anchor-thumb.jpg?fit=1000%2C500&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1511","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\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=1511"}],"version-history":[{"count":9,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1511\/revisions"}],"predecessor-version":[{"id":1540,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1511\/revisions\/1540"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/1526"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=1511"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=1511"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=1511"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}