{"id":7147,"date":"2025-09-17T08:49:38","date_gmt":"2025-09-17T13:49:38","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=7147"},"modified":"2025-09-17T08:49:39","modified_gmt":"2025-09-17T13:49:39","slug":"css-offset-and-animation-composition-for-rotating-menus","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/css-offset-and-animation-composition-for-rotating-menus\/","title":{"rendered":"CSS\u00a0offset\u00a0and\u00a0animation-composition\u00a0for Rotating Menus"},"content":{"rendered":"\n<p>Circular menu design exists as a space-saver or choice, and there\u2019s an easy and efficient way to create and animate it in CSS using&nbsp;<code>offset<\/code>&nbsp;and&nbsp;<code>animation-composition<\/code>. Here are some examples (click the button in the center of the choices):<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_JoYeQEe\" src=\"\/\/codepen.io\/anon\/embed\/JoYeQEe?height=450&amp;theme-id=1&amp;slug-hash=JoYeQEe&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed JoYeQEe\" title=\"CodePen Embed JoYeQEe\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_jEbQjBm\" src=\"\/\/codepen.io\/anon\/embed\/jEbQjBm?height=450&amp;theme-id=1&amp;slug-hash=jEbQjBm&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed jEbQjBm\" title=\"CodePen Embed jEbQjBm\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_WbQmdxR\" src=\"\/\/codepen.io\/anon\/embed\/WbQmdxR?height=450&amp;theme-id=1&amp;slug-hash=WbQmdxR&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed WbQmdxR\" title=\"CodePen Embed WbQmdxR\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>I\u2019ll take you through the second example to cover the basics.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-layout\">The Layout<\/h2>\n\n\n\n<p>Just some semantic HTML here. Since we&#8217;re offering a menu of options, a <code>&lt;menu&gt;<\/code> seems appropriate (yes, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Reference\/Elements\/menu\"><code>&lt;li&gt;<\/code> is correct as a child<\/a>!) and each button is focusable.<\/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\">main<\/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\">\"menu-wrapper\"<\/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>Poland<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>Brazil<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>Qatar<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-comment\">&lt;!-- etc. --&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\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"menu-button\"<\/span> <span class=\"hljs-attr\">onclick<\/span>=<span class=\"hljs-string\">\"revolve()\"<\/span>&gt;<\/span>See More<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/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>Other important bits:<\/p>\n\n\n\n<p>The menu and the menu button (<code>&lt;button id=\"menu-button\"&gt;<\/code>) are the same size and shape and stacked on top of each other.<\/p>\n\n\n\n<p>Half of the menu is hidden via <code>overflow: clip;<\/code> and the menu wrapper being pulled upwards.<\/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 shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">main<\/span> { \n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">overflow<\/span>: clip;\n<\/span><\/mark><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-selector-class\">.menu-wrapper<\/span> { \n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">display<\/span>: grid;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">place-items<\/span>: center;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">transform<\/span>: <span class=\"hljs-built_in\">translateY<\/span>(-<span class=\"hljs-number\">129px<\/span>);\n<\/span><\/mark><span class='shcb-loc'><span>  menu, .menu-button {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">259px<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">129px<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">grid-area<\/span>: <span class=\"hljs-number\">1<\/span> \/ <span class=\"hljs-number\">1<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">50%<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/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>Set the menu items (<code>&lt;li&gt;<\/code>s) around the&nbsp;<code>&lt;menu&gt;<\/code>\u2019s center using&nbsp;<code>offset<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">menu<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">30px<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">--gap<\/span>: <span class=\"hljs-number\">10%<\/span>; <span class=\"hljs-comment\">\/* The in-between gap for the 10 items *\/<\/span>\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">li<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">offset<\/span>: padding-box <span class=\"hljs-number\">0deg<\/span>;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">offset-distance<\/span>: <span class=\"hljs-built_in\">calc<\/span>((sibling-index() - <span class=\"hljs-number\">1<\/span>) * <span class=\"hljs-built_in\">var<\/span>(--gap)); \n<\/span><\/mark><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/* or <\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">    &amp;:nth-of-type(2) { offset-distance: calc(1 * var(--gap)); }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">    &amp;:nth-of-type(3) { offset-distance: calc(2 * var(--gap)); }<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">    etc...<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">  *\/<\/span>\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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 <code>offset<\/code> (a longhand property) positions all the <code>&lt;li&gt;<\/code> elements along the <code>&lt;menu&gt;<\/code>\u2019s <code>padding-box<\/code> that has been set as the <em>offset path<\/em>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The <strong>offset<\/strong> CSS shorthand property sets all the properties required for animating an element along a defined path. The offset properties together help to define an offset transform, a transform that aligns a point in an element (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset-anchor\">offset-anchor<\/a>) to an offset position (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset-position\">offset-position<\/a>) on a path (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset-path\">offset-path<\/a>) at various points along the path (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset-distance\">offset-distance<\/a>) and optionally rotates the element (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset-rotate\">offset-rotate<\/a>) to follow the direction of the path. \u2014 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/offset\">MDN Web Docs<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>The <code>offset-distance<\/code> is set to spread the menu items along the path based on the given gap between them (<code>--gap: 10%<\/code>).<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Items<\/th><th>Initial value of <code>offset-distance<\/code><\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td>0%<\/td><\/tr><tr><td>2<\/td><td>10%<\/td><\/tr><tr><td>3<\/td><td>20%<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation\">The Animation<\/h2>\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-keyword\">@keyframes<\/span> rev1 { \n  <span class=\"hljs-selector-tag\">to<\/span> {\n    <span class=\"hljs-attribute\">offset-distance<\/span>: <span class=\"hljs-number\">50%<\/span>;\n  } \n}\n\n<span class=\"hljs-keyword\">@keyframes<\/span> rev2 { \n  <span class=\"hljs-selector-tag\">from<\/span> {\n    <span class=\"hljs-attribute\">offset-distance<\/span>: <span class=\"hljs-number\">50%<\/span>;\n  } \n  <span class=\"hljs-selector-tag\">to<\/span> {\n    <span class=\"hljs-attribute\">offset-distance<\/span>: <span class=\"hljs-number\">0%<\/span>;\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>Set two&nbsp;<code>@keyframes<\/code>&nbsp;animations to move the menu items halfway to the left, clockwise, (<code>rev1<\/code>), and then from that position back to the right (<code>rev2<\/code>)<\/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 shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">li<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/* ... *\/<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation<\/span>: <span class=\"hljs-number\">1s<\/span> forwards;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">animation-composition<\/span>: add; \n<\/span><\/mark><span class='shcb-loc'><span>}\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\">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>Set&nbsp;<code>animation-time<\/code>&nbsp;(<code>1s<\/code>) and&nbsp;<code>animation-direction<\/code>&nbsp;(<code>forwards<\/code>), and&nbsp;<code>animation-composition<\/code>&nbsp;(<code>add<\/code>) for the&nbsp;<code>&lt;li&gt;<\/code>&nbsp;elements<\/p>\n\n\n\n<p>Even though animations can be triggered in CSS \u2014 for example, within a <code>:checked<\/code> state \u2014 since we\u2019re using a <code>&lt;button&gt;<\/code>, the names of the animations will be set in the <code>&lt;button&gt;<\/code>\u2019s click handler to trigger the animations.<\/p>\n\n\n\n<p>By using <code>animation-composition<\/code>, the animations are made to <em>add<\/em>, not replace by default, the <code>offset-distance<\/code> values inside the <code>@keyframes<\/code> rulesets to the initial <code>offset-distance<\/code> values of each of the <code>&lt;li&gt;<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Items<\/th><th>Initial Value<\/th><th>to<\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td>0%<\/td><td>(0% + 50%) <strong>50%<\/strong><\/td><\/tr><tr><td>2<\/td><td>10%<\/td><td>(10% + 50%) <strong>60%<\/strong><\/td><\/tr><tr><td>3<\/td><td>20%<\/td><td>(20% + 50%) <strong>70%<\/strong><\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">rev1 animation w\/ <code>animation-composition: add<\/code><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Items<\/th><th>from<\/th><th>back to Initial Value<\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td>(0% + 50%) <strong>50%<\/strong><\/td><td>(0% + 0%) <strong>0%<\/strong><\/td><\/tr><tr><td>2<\/td><td>(10% + 50%) <strong>60%<\/strong><\/td><td>(10% + 0%) <strong>10%<\/strong><\/td><\/tr><tr><td>3<\/td><td>(20% + 50%) <strong>70%<\/strong><\/td><td>(20% + 0%) <strong>20%<\/strong><\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">rev2 animation w\/ <code>animation-composition: add<\/code><\/figcaption><\/figure>\n\n\n\n<p>Here\u2019s how it <em>would\u2019ve been<\/em> without <code>animation-composition: add<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Items<\/th><th>Initial Value<\/th><th>to<\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td>0%<\/td><td>50%<\/td><\/tr><tr><td>2<\/td><td>10%<\/td><td>50%<\/td><\/tr><tr><td>3<\/td><td>20%<\/td><td>50%<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The&nbsp;<strong>animation-composition<\/strong>&nbsp;CSS property specifies the&nbsp;<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/Composite_operation\">composite operation<\/a>&nbsp;to use when multiple animations affect the same property simultaneously.<\/p>\n<cite><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/animation-composition\">MDN Web Docs<\/a><\/cite><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-trigger\">The Trigger<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> LI = <span class=\"hljs-built_in\">document<\/span>.querySelectorAll(<span class=\"hljs-string\">'li'<\/span>);\n<span class=\"hljs-keyword\">let<\/span> flag = <span class=\"hljs-literal\">true<\/span>;\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">revolve<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  LI.forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">li<\/span> =&gt;<\/span> li.style.animationName = flag ? <span class=\"hljs-string\">\"rev1\"<\/span> : <span class=\"hljs-string\">\"rev2\"<\/span>);\n  flag = !flag;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>In the menu button\u2019s click handler, <code>revolve()<\/code>, set the <code>&lt;li&gt;<\/code> elements\u2019 <code>animationName<\/code> to <code>rev1<\/code> and <code>rev2<\/code>, alternatively.<\/p>\n\n\n\n<p>Assigning the animation name triggers the corresponding keyframes animation each time the <code>&lt;button&gt;<\/code> is clicked.<\/p>\n\n\n\n<p>Using the method covered in this post, it\u2019s possible to control how much along a revolution the elements are to move (demo one), and which direction. You can also experiment with different offset path shapes. You can declare (<code>@keyframes<\/code>) and trigger (<code>:checked<\/code>, <code>:hover<\/code>, etc.) the animations in CSS, or using JavaScript\u2019s <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/KeyframeEffect\">Web Animations API<\/a> that includes the animation composition property.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The article explains how to design and animate a *circular* menu (that rotates in a circle!) in CSS using offset and animation-composition.<\/p>\n","protected":false},"author":20,"featured_media":7176,"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":[100,369,7,397,353],"class_list":["post-7147","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-animation","tag-animation-composition","tag-css","tag-menu","tag-offset-path"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/09\/CSS-offset-and-animation-composition-for-Rotating-Menus.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7147","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\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=7147"}],"version-history":[{"count":12,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7147\/revisions"}],"predecessor-version":[{"id":7194,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7147\/revisions\/7194"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/7176"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=7147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=7147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=7147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}