{"id":5489,"date":"2025-03-31T11:55:52","date_gmt":"2025-03-31T16:55:52","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=5489"},"modified":"2025-03-31T11:55:53","modified_gmt":"2025-03-31T16:55:53","slug":"reanimating-the-css-day-buttons","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/reanimating-the-css-day-buttons\/","title":{"rendered":"Reanimating the CSS Day Buttons"},"content":{"rendered":"\n<p>Are you as excited about&nbsp;<a href=\"https:\/\/cssday.nl\/\">CSS Day<\/a>&nbsp;as I am? While browsing the conference website, I couldn\u2019t help but notice their big firebrick-red buttons. A website isn&#8217;t just about displaying content, it\u2019s about creating excitement. Every interaction should feel polished and engaging, especially buttons, which are the primary way users navigate the site.<\/p>\n\n\n\n<p>A well-animated button can capture attention, reinforce branding, and make the experience more enjoyable. In this article, we&#8217;ll take a closer look at the existing buttons and explore ways to enhance them with modern CSS techniques.<\/p>\n\n\n\n<p>First, here is a version of the button that is currently on the website. Hover over the button to see its shape change.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_WbNyQYm\/ef4f1b35bbe8479df7efd5dfeeccf4b9\" src=\"\/\/codepen.io\/anon\/embed\/WbNyQYm\/ef4f1b35bbe8479df7efd5dfeeccf4b9?height=450&amp;theme-id=47434&amp;slug-hash=WbNyQYm\/ef4f1b35bbe8479df7efd5dfeeccf4b9&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed WbNyQYm\/ef4f1b35bbe8479df7efd5dfeeccf4b9\" title=\"CodePen Embed WbNyQYm\/ef4f1b35bbe8479df7efd5dfeeccf4b9\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>The\u00a0<code>a<\/code>\u00a0element is wrapped with a\u00a0<code>div<\/code>\u00a0that has a solid background color, and the\u00a0<code>hover<\/code>\u00a0effect sets the\u00a0<code>div<\/code>&#8216;s background to\u00a0<code>transparent<\/code>, revealing the\u00a0<code>a<\/code>&#8216;s arrow shape, created using a\u00a0<code>clip-path<\/code>. The transition between the states (the \u2018fade\u2019 of the background) creates weird looking triangles.<\/p>\n\n\n\n<p>I think that we can improve on that by using some movement and dynamics.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Approach 1: Background Image Animations<\/h2>\n\n\n\n<p>One simple-yet-effective way to add flair to buttons is by animating a\u00a0<code>background-image<\/code>. Well, we&#8217;re not really animating the image, but we can achieve a smooth transition effect that feels dynamic by animating the\u00a0<code>background-position<\/code>\u00a0property.<\/p>\n\n\n\n<p>Here is a button that uses a linear transition on the\u00a0<code>background-position<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" 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\">button<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">2px<\/span> solid firebrick;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">linear-gradient<\/span>(<span class=\"hljs-number\">120deg<\/span>, white <span class=\"hljs-number\">50%<\/span>, firebrick <span class=\"hljs-number\">0<\/span>) <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span>\/ <span class=\"hljs-number\">250%<\/span> <span class=\"hljs-number\">100%<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">color<\/span>: firebrick;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.6em<\/span> <span class=\"hljs-number\">1em<\/span> <span class=\"hljs-number\">0.7em<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">transition<\/span>: all <span class=\"hljs-number\">0.5s<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  \n<\/span><\/span><span class='shcb-loc'><span>  &amp;:hover {\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attribute\">background-position-x<\/span>: <span class=\"hljs-number\">100%<\/span>;\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">color<\/span>: white;\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-1\"><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>In this example the background stretches the gradient horizontally to 2.5 times the width of the button, and the background\u2019s position changes from&nbsp;<code>0%<\/code>&nbsp;to&nbsp;<code>100%<\/code>. to better understand this effect, you can use the \u2018Visualize background\u2019 checkbox.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_bNGKVox\/c58004223d7df7666d577193cfcae108\" src=\"\/\/codepen.io\/anon\/embed\/bNGKVox\/c58004223d7df7666d577193cfcae108?height=450&amp;theme-id=47434&amp;slug-hash=bNGKVox\/c58004223d7df7666d577193cfcae108&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed bNGKVox\/c58004223d7df7666d577193cfcae108\" title=\"CodePen Embed bNGKVox\/c58004223d7df7666d577193cfcae108\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>So how do you use&nbsp;<code>background-position<\/code>&nbsp;to create the arrow-shaped hover effect? We\u2019ll actually need to layer two backgrounds and control both positions. Here&#8217;s how:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_XJWYmod\/7e5e1b55df5b1f2c4b696e49db9d9056\" src=\"\/\/codepen.io\/anon\/embed\/XJWYmod\/7e5e1b55df5b1f2c4b696e49db9d9056?height=450&amp;theme-id=47434&amp;slug-hash=XJWYmod\/7e5e1b55df5b1f2c4b696e49db9d9056&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed XJWYmod\/7e5e1b55df5b1f2c4b696e49db9d9056\" title=\"CodePen Embed XJWYmod\/7e5e1b55df5b1f2c4b696e49db9d9056\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>The pointed shape is created using two simple&nbsp;<code>conic-gradients<\/code>, and again, the background stretches each gradient to 2.5 times the width of the button, so we can set the&nbsp;<code>background-position<\/code>&nbsp;to bring the center of these conics in and out of view.<\/p>\n\n\n\n<p>This method can actually be quite powerful and is great for many applications. And while I love using (and animating) background gradients, maybe for this specific use case it\u2019s not the best option. So let\u2019s try something else\u2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Approach 2: Clip-Path Transition<\/h2>\n\n\n\n<p>Another way to animate shapes in CSS is by using clipping, allowing us to create unique shapes and transitions. In our case, the buttons already have a&nbsp;<code>clip-path<\/code>&nbsp;property, so let\u2019s use it. We\u2019ll set it to the&nbsp;<code>hover<\/code>&nbsp;state, and \u2018reset\u2019 the&nbsp;<code>polygon<\/code>&nbsp;on idle.<\/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-class\">.button<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">display<\/span>: block;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">border<\/span>: none;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">var<\/span>(--yearColour);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">color<\/span>: white;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.6em<\/span> <span class=\"hljs-number\">1em<\/span> <span class=\"hljs-number\">0.7em<\/span>;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">clip-path<\/span>: <span class=\"hljs-built_in\">polygon<\/span>(<span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">100%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">100%<\/span> <span class=\"hljs-number\">50%<\/span>, <span class=\"hljs-number\">100%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">50%<\/span>);\n<\/span><\/mark><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">transition<\/span>: clip-path <span class=\"hljs-number\">0.5s<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  &amp;:hover {\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attribute\">clip-path<\/span>: <span class=\"hljs-built_in\">polygon<\/span>(<span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">95%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">100%<\/span> <span class=\"hljs-number\">50%<\/span>, <span class=\"hljs-number\">95%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">5%<\/span> <span class=\"hljs-number\">50%<\/span>);\n<\/span><\/mark><span class='shcb-loc'><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 class=\"learn-more\">Note that in order to transition the movement, <strong>the number of nodes<\/strong> in the\u00a0<code>polygon<\/code>\u00a0shapes must be the same.<\/p>\n\n\n\n<p>This approach already looks nice, but I think we can do better. <\/p>\n\n\n\n<p>When working with\u00a0<code>clip-path<\/code>\u00a0(and clipping in general) you need to remember that the clipping is inwards, removing parts of your elements, and you can\u2019t overflow anything outside the clipped area. If we do want to expand outward from our element, we need to first expend the element itself, and then adjust the clipping.<\/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-class\">.button-v2<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">display<\/span>: block;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">border<\/span>: none;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">var<\/span>(--yearColour);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">color<\/span>: white;\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.6em<\/span> <span class=\"hljs-number\">1.3em<\/span> <span class=\"hljs-number\">0.7em<\/span>;\n<\/span><\/mark><mark class='shcb-loc'><span>  <span class=\"hljs-attribute\">clip-path<\/span>: <span class=\"hljs-built_in\">polygon<\/span>(<span class=\"hljs-number\">2.5%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">97.5%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">97.5%<\/span> <span class=\"hljs-number\">50%<\/span>, <span class=\"hljs-number\">97.5%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">2.5%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">2.5%<\/span> <span class=\"hljs-number\">50%<\/span>);\n<\/span><\/mark><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">transition<\/span>: clip-path <span class=\"hljs-number\">0.5s<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  &amp;:hover {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">clip-path<\/span>: <span class=\"hljs-built_in\">polygon<\/span>(<span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">95%<\/span> <span class=\"hljs-number\">0%<\/span>, <span class=\"hljs-number\">100%<\/span> <span class=\"hljs-number\">50%<\/span>, <span class=\"hljs-number\">95%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">0%<\/span> <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">5%<\/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-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>In the above example I\u2019ve increased the inline&nbsp;<code>padding<\/code>, making the element wider, then adjusted the idle state of the&nbsp;<code>polygon<\/code>&nbsp;to remove the added width. Now the clipping is not just inward, but also expands out, which not only creates a more dynamic effect but also reduces the risk of cutting into the button\u2019s content.<\/p>\n\n\n\n<p>Here is a live demo of the two versions, In my opinion, this second shape looks slightly better overall. Which one do you like?<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_JojZGYy\/6674e579a9b6b978bb4d685b9da453d7\" src=\"\/\/codepen.io\/anon\/embed\/JojZGYy\/6674e579a9b6b978bb4d685b9da453d7?height=450&amp;theme-id=47434&amp;slug-hash=JojZGYy\/6674e579a9b6b978bb4d685b9da453d7&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed JojZGYy\/6674e579a9b6b978bb4d685b9da453d7\" title=\"CodePen Embed JojZGYy\/6674e579a9b6b978bb4d685b9da453d7\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Solving the Challenge of the Dotted Button<\/h3>\n\n\n\n<p>While the previous techniques work well for solid buttons, the CSS Day website also has a dotted-style button. These require a different approach, since&nbsp;<code>background-image<\/code>&nbsp;and&nbsp;<code>clip-path<\/code>&nbsp;alone don\u2019t handle dotted outlines effectively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Approach 3: Pseudo-Elements and Transforms<\/h2>\n\n\n\n<p>Somehow, whenever there&#8217;s an animation or interaction that feels tricky to implement, it often turns out that pseudo-elements (e.g. <code>::before<\/code> and <code>::after<\/code>) are the solution. They\u2019re like the hidden superpower of every element, allowing us to do some really cool things.<\/p>\n\n\n\n<p>In this case, we can achieve a clean and elegant solution using pseudo-elements. The idea is pretty straightforward: ensure each pseudo-element spans the full width of the button and half the height. We place one element at the top of the button and the second at the bottom. Then, on hover, we apply a skew transformation to the elements. Simple enough? Here\u2019s a live demo:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_QwWxdbx\/b65776eb3e1d1450413e511aa3395596\" src=\"\/\/codepen.io\/anon\/embed\/QwWxdbx\/b65776eb3e1d1450413e511aa3395596?height=450&amp;theme-id=47434&amp;slug-hash=QwWxdbx\/b65776eb3e1d1450413e511aa3395596&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed QwWxdbx\/b65776eb3e1d1450413e511aa3395596\" title=\"CodePen Embed QwWxdbx\/b65776eb3e1d1450413e511aa3395596\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>Let&#8217;s break down what we added:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We applied&nbsp;<code>position: relative;<\/code>&nbsp;to the button as we\u2019re going to position the pseudo-elements using&nbsp;<code>position: absolute<\/code>.<\/li>\n\n\n\n<li>For the pseudo-elements, we started with shared styling: positioning, size, color,&nbsp;<code>z-index<\/code>, and of course, a&nbsp;<code>transition<\/code>&nbsp;so everything moves smoothly.<\/li>\n\n\n\n<li>The&nbsp;<code>::before<\/code>&nbsp;pseudo-element is placed at&nbsp;<code>top: 0;<\/code>&nbsp;to serve as the background for the top half of the button, and the&nbsp;<code>::after<\/code>&nbsp;pseudo-element is positioned at&nbsp;<code>bottom: 0;<\/code>&nbsp;to cover the bottom half.<\/li>\n\n\n\n<li>We added a&nbsp;<code>transform<\/code>&nbsp;with a simple&nbsp;<code>skew<\/code>&nbsp;function along the X-axis, and used&nbsp;<code>calc<\/code>&nbsp;to adjust the direction of the skew in the&nbsp;<code>::after<\/code>&nbsp;element so the skew effects are applied in two different directions.<\/li>\n\n\n\n<li>The last thing we added is a&nbsp;<code>hover<\/code>&nbsp;state that defines the desired skew angle, transforming the button into an arrow shape.<\/li>\n<\/ul>\n\n\n\n<p>So how do pseudo-elements help us solve the dotted button challenge? It&#8217;s simple: all we need to do is change the text color of the button and the background color of the pseudo-elements, then apply a dotted border. The key is to ensure that the&nbsp;<code>::before<\/code>&nbsp;has a border on the sides and top, while the&nbsp;<code>::after<\/code>&nbsp;gets a border on the sides and bottom.<\/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-class\">.button<\/span><span class=\"hljs-selector-class\">.dotted<\/span> {\n  <span class=\"hljs-attribute\">color<\/span>: firebrick;\n\n  &amp;::before, &amp;::after {\n    <span class=\"hljs-attribute\">background-color<\/span>: white;\n    <span class=\"hljs-attribute\">border<\/span>: dotted firebrick;\n  }\n  &amp;<span class=\"hljs-selector-pseudo\">::before<\/span> {\n    <span class=\"hljs-attribute\">border-width<\/span>: <span class=\"hljs-number\">2px<\/span> <span class=\"hljs-number\">2px<\/span> <span class=\"hljs-number\">0<\/span>;\n  }\n  &amp;<span class=\"hljs-selector-pseudo\">::after<\/span> {\n    <span class=\"hljs-attribute\">border-width<\/span>: <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">2px<\/span> <span class=\"hljs-number\">2px<\/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>That\u2019s it. I\u2019ve also added a version that changes the button color after the shape shifts on hover. Here are live examples of both versions:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_OPJEWjv\/7b3fee6124202c15d3c263e4b0f89b71\" src=\"\/\/codepen.io\/anon\/embed\/OPJEWjv\/7b3fee6124202c15d3c263e4b0f89b71?height=450&amp;theme-id=47434&amp;slug-hash=OPJEWjv\/7b3fee6124202c15d3c263e4b0f89b71&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed OPJEWjv\/7b3fee6124202c15d3c263e4b0f89b71\" title=\"CodePen Embed OPJEWjv\/7b3fee6124202c15d3c263e4b0f89b71\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wrapping-up\">Wrapping Up<\/h2>\n\n\n\n<p>We\u2019ve reanimated the CSS Day 2025 buttons by experimenting with different CSS techniques:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Background-image animations<\/strong>&nbsp;for smooth gradient transitions.<\/li>\n\n\n\n<li><strong>Clip-path effects<\/strong>&nbsp;for unique button shapes.<\/li>\n\n\n\n<li><strong>Pseudo-elements<\/strong>&nbsp;to create a dynamic dotted button effect.<\/li>\n<\/ol>\n\n\n\n<p>Each approach offers distinct advantages (and some drawbacks), and it\u2019s important to familiarize ourselves with various animation options so that we can choose the most suitable one for each case based on the design needs, the desired effect, and the button\u2019s context<\/p>\n\n\n\n<p>Want to take this further? Try incorporating CSS Variables for more flexibility or mixing in&nbsp;<code>@keyframes<\/code>&nbsp;for even more animation control. Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>These buttons animate from a square to an arrow, and we look at three different ways to do it, each with their own upsides. <\/p>\n","protected":false},"author":27,"featured_media":5506,"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":[234,93,216,7,318],"class_list":["post-5489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-background-clip","tag-buttons","tag-clip-path","tag-css","tag-pseudo-elements"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/03\/CSS-Day-2025.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5489","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\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=5489"}],"version-history":[{"count":5,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5489\/revisions"}],"predecessor-version":[{"id":5508,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5489\/revisions\/5508"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/5506"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=5489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=5489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=5489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}