{"id":5467,"date":"2025-03-28T09:47:04","date_gmt":"2025-03-28T14:47:04","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=5467"},"modified":"2025-04-01T10:47:51","modified_gmt":"2025-04-01T15:47:51","slug":"expanding-css-shadow-effects","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/expanding-css-shadow-effects\/","title":{"rendered":"Expanding CSS Shadow Effects"},"content":{"rendered":"\n<p>Design principles tell us a shadow is conveys that light is hiding an object, which casts the shadow behind it, giving us a sense of depth. However, if that\u2019s <em>all<\/em> a shadow is ever used for, then it has not been utilized to its full potential.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Power of Shadows<\/h2>\n\n\n\n<p>Shadows in CSS can be multi-directional, layered, and are animate-able. On top of being all that, they don\u2019t affect the layout and computed size of an element even though they can make it <em>appear<\/em> bigger or smaller, which makes them an efficient tool for making visual changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Types of Shadows<\/h2>\n\n\n\n<p>There are different types of shadows based on the type of component they affect.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>box-shadow<\/code><\/li>\n\n\n\n<li><code>filter: drop-shadow()<\/code><\/li>\n\n\n\n<li><code>text-shadow<\/code><\/li>\n<\/ul>\n\n\n\n<details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>The difference between box-shadow and drop-shadow() is worth knowing!<\/summary>\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_nwBzXJ\" src=\"\/\/codepen.io\/anon\/embed\/nwBzXJ?height=450&amp;theme-id=47434&amp;slug-hash=nwBzXJ&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed nwBzXJ\" title=\"CodePen Embed nwBzXJ\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/details>\n\n\n\n<p>All of this is proof that you\u2019ll benefit from understanding CSS shadows and learning ways to expand their uses beyond simply creating a proverbial shadow.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Focus on Inset Box Shadows<\/h2>\n\n\n\n<p>In this article, for the purpose of simplicity, my examples will focus on <em>box shadows<\/em>, specifically, <em>inset box shadows<\/em>. However, the principles we\u2019ll be working with are same for all types of CSS shadows.<\/p>\n\n\n\n<p>Below is an example of what could be possible with the things I\u2019ll be covering in this article. I\u2019ll show you more examples and design variants as we proceed further.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_zxYLrJz\" src=\"\/\/codepen.io\/anon\/embed\/zxYLrJz?height=500&amp;theme-id=47434&amp;slug-hash=zxYLrJz&amp;default-tab=result\" height=\"500\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed zxYLrJz\" title=\"CodePen Embed zxYLrJz\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>To warm up, let\u2019s just go ahead and animate a group of inset box shadows, via a <code>transition: box-shadow ... ;<\/code>,   and see what we get.<\/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\">\"pokemon golduck\"<\/span>&gt;<\/span>\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"text\"<\/span>&gt;<\/span>Golduck<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>&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<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\">.pokemon<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">box-shadow<\/span>: \n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">10px<\/span> <span class=\"hljs-number\">#eee<\/span>, \n<\/span><\/span><span class='shcb-loc'><span>    inset <span class=\"hljs-number\">3px<\/span> <span class=\"hljs-number\">3px<\/span> <span class=\"hljs-number\">10px<\/span> white, \n<\/span><\/span><span class='shcb-loc'><span>    inset -<span class=\"hljs-number\">160px<\/span> -<span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">0<\/span> royalblue, \n<\/span><\/span><span class='shcb-loc'><span>    inset <span class=\"hljs-number\">160px<\/span> -<span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">0<\/span> green,\n<\/span><\/span><span class='shcb-loc'><span>    inset -<span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">0<\/span> blue, \n<\/span><\/span><span class='shcb-loc'><span>    inset <span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">160px<\/span> <span class=\"hljs-number\">0<\/span> yellow;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  &amp;:hover {\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attribute\">box-shadow<\/span>: none;\n<\/span><\/mark><mark class='shcb-loc'><span>    <span class=\"hljs-attribute\">transition<\/span>: box-shadow linear <span class=\"hljs-number\">0.6s<\/span>;\n<\/span><\/mark><span class='shcb-loc'><span>    .text { <span class=\"hljs-attribute\">opacity<\/span>: <span class=\"hljs-number\">0<\/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<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_mydjVza\" src=\"\/\/codepen.io\/anon\/embed\/mydjVza?height=510&amp;theme-id=47434&amp;slug-hash=mydjVza&amp;default-tab=result\" height=\"510\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed mydjVza\" title=\"CodePen Embed mydjVza\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>The above shows off the <code>inset<\/code> keyword that <code>box-shadow<\/code> can use in a couple of different ways. Inward shadows make for terrific overlays, since it\u2019s painted on <em>top<\/em> of an element\u2019s background and originates from the edges of the element\u2019s <em>padding box<\/em>. The other thing we got to confirm is that the <code>box-shadow<\/code> is indeed animate-able.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Changing the Shadow&#8217;s Shape<\/h2>\n\n\n\n<p>CSS shadows, by default, follow the shape of the component they are applied to \u2014 a box, text, or the opaque area of an element, depending on which shadow is used. By playing around with the shadows\u2019 vertical and horizontal offsets, you can reshape them to a degree. Here\u2019s an example:<\/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\"><span class=\"hljs-selector-class\">.selected<\/span> {\n  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n  <span class=\"hljs-attribute\">box-shadow<\/span>: \n    inset -<span class=\"hljs-number\">30px<\/span> <span class=\"hljs-number\">30px<\/span> <span class=\"hljs-number\">0<\/span> white, \n    inset <span class=\"hljs-number\">30px<\/span> -<span class=\"hljs-number\">30px<\/span> <span class=\"hljs-number\">0<\/span> white,\n    inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">80px<\/span> lime;\n  <span class=\"hljs-attribute\">transform<\/span>: <span class=\"hljs-built_in\">rotatez<\/span>(<span class=\"hljs-number\">360deg<\/span>);\n  <span class=\"hljs-attribute\">transition<\/span>: transform <span class=\"hljs-number\">1s<\/span> linear;\n}<\/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 element we&#8217;ll apply this to is already a circle, and this will make the shadow somewhat football (\ud83c\udfc8) shaped.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_ZYEjQmL\" src=\"\/\/codepen.io\/anon\/embed\/ZYEjQmL?height=580&amp;theme-id=47434&amp;slug-hash=ZYEjQmL&amp;default-tab=result\" height=\"580\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed ZYEjQmL\" title=\"CodePen Embed ZYEjQmL\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>In similar ways you can play around with a shadow\u2019s <em>blur radius<\/em>, <em>spread distance<\/em> (in <code>box-shadow<\/code>), and <em>color<\/em>.<\/p>\n\n\n\n<p class=\"learn-more\"><strong>Tip<\/strong>: Add a thin border matching the page\u2019s background to the element if there\u2019s any inset shadow bleeding outside the box<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Animating Only Parts of a Shadow<\/h2>\n\n\n\n<p>We can take this a step further. So far we\u2019ve been animating the <code>box-shadow<\/code> property as a whole, but how about <a href=\"https:\/\/css-tricks.com\/now-css-custom-properties-thing-value-parts-can-changed-individually\/\">pin-pointing the animation to individual values<\/a> of a shadow? That will not only produce a different result, but you can also assign different animation times for different aspects of a shadow:&nbsp;<\/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-keyword\">@property<\/span> --l {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">length<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: 0<span class=\"hljs-selector-tag\">px<\/span>;\n}\n<span class=\"hljs-keyword\">@property<\/span> --c {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">color<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: <span class=\"hljs-selector-tag\">red<\/span>;\n}\n<span class=\"hljs-selector-class\">.selected<\/span> {\n  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n  <span class=\"hljs-attribute\">--l<\/span>: <span class=\"hljs-number\">160px<\/span>;\n  <span class=\"hljs-attribute\">--c<\/span>: black;\n  <span class=\"hljs-attribute\">box-shadow<\/span>: inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">var<\/span>(--c);\n  <span class=\"hljs-attribute\">transition<\/span>: --l <span class=\"hljs-number\">1s<\/span> linear, --c <span class=\"hljs-number\">0.5s<\/span> linear;\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<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_vEYaLQQ\" src=\"\/\/codepen.io\/anon\/embed\/vEYaLQQ?height=600&amp;theme-id=47434&amp;slug-hash=vEYaLQQ&amp;default-tab=result\" height=\"600\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed vEYaLQQ\" title=\"CodePen Embed vEYaLQQ\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>You can also use <code>@keyframes<\/code>, instead of <code>transition<\/code>, for the animations to keep frame stops. For instance, in the following example, there\u2019s multiple color changes throughout the animation sequence as defined by the <code>@keyframes<\/code> ruleset, <code>colorChange<\/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\"><span class=\"hljs-keyword\">@property<\/span> --c {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">color<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: <span class=\"hljs-selector-tag\">dodgerblue<\/span>;\n}\n<span class=\"hljs-keyword\">@keyframes<\/span> colorChange {\n  40% { <span class=\"hljs-attribute\">--c<\/span>: yellow }\n  80% { <span class=\"hljs-attribute\">--c<\/span>: red }\n}\n<span class=\"hljs-selector-class\">.selected<\/span> {\n  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n  <span class=\"hljs-attribute\">box-shadow<\/span>: inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">var<\/span>(--c);\n  <span class=\"hljs-attribute\">animation<\/span>: <span class=\"hljs-number\">1s<\/span> linear colorChange;\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><a href=\"https:\/\/codepen.io\/rpsthecoder\/pen\/mydGZLE\">Here&#8217;s a demo of that.<\/a><\/p>\n\n\n\n<p>For our main demo, let&#8217;s keep <code>transition<\/code>, and then combine the things we\u2019ve seen so far as well as include a few more colors.&nbsp;<\/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-keyword\">@property<\/span> --l {\n  <span class=\"hljs-selector-tag\">syntax<\/span>: \"&lt;<span class=\"hljs-selector-tag\">length<\/span>&gt;\";\n  <span class=\"hljs-selector-tag\">inherits<\/span>: <span class=\"hljs-selector-tag\">false<\/span>;\n  <span class=\"hljs-selector-tag\">initial-value<\/span>: 0<span class=\"hljs-selector-tag\">px<\/span>;\n}\n<span class=\"hljs-selector-class\">.selected<\/span> {\n  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n  <span class=\"hljs-attribute\">--l<\/span>: <span class=\"hljs-number\">100px<\/span>;\n  <span class=\"hljs-attribute\">box-shadow<\/span>: \n    inset <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-number\">60px<\/span> azure,\n    inset <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-number\">60px<\/span> white,\n    inset <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-number\">60px<\/span> white,\n    inset <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-number\">60px<\/span> white,\n    inset <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-number\">5px<\/span> fuchsia,\n    inset <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-number\">5px<\/span> lime, inset <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-number\">5px<\/span> red,\n    inset <span class=\"hljs-built_in\">calc<\/span>(-<span class=\"hljs-number\">1<\/span> * var(--l)) <span class=\"hljs-built_in\">var<\/span>(--l) <span class=\"hljs-number\">5px<\/span> green;\n  <span class=\"hljs-attribute\">transition<\/span>: --l <span class=\"hljs-number\">1s<\/span> linear;\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<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_emYjJbv\" src=\"\/\/codepen.io\/anon\/embed\/emYjJbv?height=520&amp;theme-id=47434&amp;slug-hash=emYjJbv&amp;default-tab=result\" height=\"520\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed emYjJbv\" title=\"CodePen Embed emYjJbv\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\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\">.selected<\/span> {\n  <span class=\"hljs-comment\">\/* etc. *\/<\/span>\n  <span class=\"hljs-attribute\">box-shadow<\/span>: \n    inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">10px<\/span> <span class=\"hljs-number\">30px<\/span> white, \n    inset -<span class=\"hljs-number\">40px<\/span> <span class=\"hljs-number\">0px<\/span> <span class=\"hljs-number\">0<\/span> white,\n    inset <span class=\"hljs-number\">40px<\/span> <span class=\"hljs-number\">0px<\/span> <span class=\"hljs-number\">0<\/span> white, \n    inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">100px<\/span> red, \n    inset <span class=\"hljs-number\">0<\/span> -<span class=\"hljs-number\">60px<\/span> <span class=\"hljs-number\">0<\/span> white, \n    inset <span class=\"hljs-number\">60px<\/span> <span class=\"hljs-number\">30px<\/span> <span class=\"hljs-number\">0<\/span> white, \n    inset <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">0<\/span> <span class=\"hljs-number\">100px<\/span> blue;\n  <span class=\"hljs-attribute\">transform<\/span>: <span class=\"hljs-built_in\">rotatez<\/span>(<span class=\"hljs-number\">360deg<\/span>);\n  <span class=\"hljs-attribute\">transition<\/span>: box-shadow <span class=\"hljs-number\">1s<\/span> linear, transform <span class=\"hljs-number\">1s<\/span> linear;\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<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_zxYLrJz\" src=\"\/\/codepen.io\/anon\/embed\/zxYLrJz?height=520&amp;theme-id=47434&amp;slug-hash=zxYLrJz&amp;default-tab=result\" height=\"520\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed zxYLrJz\" title=\"CodePen Embed zxYLrJz\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>This is where you can really see how layering can be helpful.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Other Examples<\/h2>\n\n\n\n<p>Here\u2019s a collection of a few on-hover animation designs using CSS shadows to help you get started:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_KwKyoKM\" src=\"\/\/codepen.io\/anon\/embed\/KwKyoKM?height=680&amp;theme-id=47434&amp;slug-hash=KwKyoKM&amp;default-tab=result\" height=\"680\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed KwKyoKM\" title=\"CodePen Embed KwKyoKM\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>If you want to keep exploring shadow animations further, I recommend combining them with other possible visual effects from CSS properties like <em>filter<\/em> and <em>blend modes<\/em>. Also, make sure to see how the animations work out both when individual values are animated and when the shadow as a whole property is animated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Further Reference<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/codepen.io\/web-dot-dev\/full\/rNjGevp\" target=\"_blank\" rel=\"noreferrer noopener\">Box shadow playground<\/a> by web.dev on CodePen<\/li>\n\n\n\n<li>\u201c<a href=\"https:\/\/www.smashingmagazine.com\/2023\/08\/interesting-ways-use-css-shadows\/\" target=\"_blank\" rel=\"noreferrer noopener\">A Few Interesting Ways To Use CSS Shadows For More Than Depth<\/a>\u201d by me on Smashing Magazine<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/@property\" target=\"_blank\" rel=\"noreferrer noopener\">CSS @property<\/a> on MDN<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Shadows don&#8217;t have to be used for&#8230; shadows. Inset shadows can layer over backgrounds and because they are animatable, it&#8217;s just another tool for drawing what we want to the page.<\/p>\n","protected":false},"author":20,"featured_media":5514,"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":[220,7],"class_list":["post-5467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-box-shadow","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/03\/Expanding-CSS-Shadow-Effects.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5467","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=5467"}],"version-history":[{"count":13,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5467\/revisions"}],"predecessor-version":[{"id":5496,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5467\/revisions\/5496"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/5514"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=5467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=5467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=5467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}