{"id":3103,"date":"2024-07-23T12:29:41","date_gmt":"2024-07-23T17:29:41","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=3103"},"modified":"2024-07-24T06:55:17","modified_gmt":"2024-07-24T11:55:17","slug":"clip-pathing-color-changes","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/clip-pathing-color-changes\/","title":{"rendered":"Clip Pathing Color Changes"},"content":{"rendered":"\n<p><a href=\"https:\/\/emilkowal.ski\/ui\/the-magic-of-clip-path\">This is a nice post from Emil Kowalski<\/a> on usage of <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/clip-path\">the <code>clip-path<\/code> property<\/a> in CSS. I&#8217;ve always liked <code>clip-path<\/code>. Maybe it&#8217;s because it&#8217;s such a sharp knife. When you clip an element, it&#8217;s <em>clipped<\/em>, yo. There isn&#8217;t a lot of nuance to it, it does what it does. But moreso, I think I like the connection to SVG (oh, hey, by the way, I just made <a href=\"https:\/\/practical-svg.chriscoyier.net\/\">my old book Practical SVG<\/a> entirely free). The value that you give <code>clip-path<\/code> is stuff like <code>circle()<\/code>, <code>polygon()<\/code>, <code>path()<\/code>, etc \u2014 the primitive shapes of SVG.<\/p>\n\n\n\n<p>In Emil&#8217;s post, my favorite example is a navigation bar where a &#8220;pill&#8221; shape animates from one navigation item to another when they are clicked. The pill is a different background color, and so the text color also changes. (If you&#8217;re over 100 years old like me, we used to call this kind of thing <a href=\"https:\/\/www.jqueryscript.net\/demo\/jQuery-Animated-Navigation-with-Sliding-Background-Lava-Lamp\/\">&#8220;lava lamp&#8221; navigation<\/a> \ud83d\udc74).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"156\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/CleanShot-2024-07-23-at-10.06.59.gif?resize=800%2C156&#038;ssl=1\" alt=\"\" class=\"wp-image-3111\" style=\"width:504px;height:auto\"\/><\/figure>\n<\/div>\n\n\n<p>I would guess most people would assume what is happening here is an extra element set behind the links that moves position to underneath the newly active links. You <em>could<\/em> do it that way, but there is a minor aesthetic issue with it. Because the <code>background-color<\/code> is changing here, the text also needs to change appropriately (from dark to light here). You could change that color instantly, but that will look weird like it&#8217;s changing too early. You could set a <code>transition<\/code> on it, but you&#8217;ll never get the fade to look quite right, especially as it has to go through an awkward gray color. <\/p>\n\n\n\n<p>Essentially, you&#8217;ll <em>never<\/em> get a state like this:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"206\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.09.32%E2%80%AFAM.png?resize=1024%2C206&#038;ssl=1\" alt=\"\" class=\"wp-image-3112\" style=\"width:519px;height:auto\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.09.32%E2%80%AFAM.png?resize=1024%2C206&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.09.32%E2%80%AFAM.png?resize=300%2C60&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.09.32%E2%80%AFAM.png?resize=768%2C155&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.09.32%E2%80%AFAM.png?w=1312&amp;ssl=1 1312w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><figcaption class=\"wp-element-caption\">This ain&#8217;t gonna happen with an underlay element alone.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>See how the text is half-light and half-dark mid-animation when the highlight blue pill moves from one to another? That&#8217;s a lovely effect that makes this feel very polished and smooth. This idea first came from <a href=\"https:\/\/x.com\/pacocoursey\/status\/1522639642155266048\">a tweet by Paco<\/a>. Like Emil says:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>You might say that not everyone is going to notice the difference, but I truly believe that small details like this add up and make the experience feel more polished. Even if they go unnoticed.<\/p>\n<\/blockquote>\n\n\n\n<p>Agreed. <\/p>\n\n\n\n<p>In Emil&#8217;s post, it&#8217;s done with React. That&#8217;s totally fine, but I figured I&#8217;d make a vanilla one for y&#8217;all here:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_ZEdOmYO\" src=\"\/\/codepen.io\/anon\/embed\/ZEdOmYO?height=450&amp;theme-id=47434&amp;slug-hash=ZEdOmYO&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed ZEdOmYO\" title=\"CodePen Embed ZEdOmYO\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>Here&#8217;s how this works:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>There is one set of semantic HTML navigation.<\/li>\n\n\n\n<li>If JavaScript executes, it duplicates the nav (we&#8217;ll need two) but ensures the duplicate is hidden for screen readers.<\/li>\n\n\n\n<li>The duplicate is placed exactly on top of the original (it&#8217;s the &#8220;blue&#8221; one) and can&#8217;t directly be clicked (i.e. <code>pointer-events: none;<\/code>)<\/li>\n\n\n\n<li>A <code>clip-path<\/code> is set that highlights one of the navigation items in particular by clipping the entire duplicate except one link.<\/li>\n\n\n\n<li>As links are clicked, the <code>clip-path<\/code> is changed using positional math, highlighting the new one. Also high-five for the <code>round<\/code> keyword that can be used with <code>inset()<\/code> for rounded corners on inset rectangles.<\/li>\n\n\n\n<li>The <code>clip-path<\/code> animates, thanks to a basic CSS <code>transition<\/code>. <\/li>\n<\/ol>\n\n\n\n<p>I think it&#8217;s cool as heck that it all comes together that cleanly. <\/p>\n\n\n\n<p>It&#8217;s also a nice touch that the new <code>clip-path<\/code> positions are calculated based on their page position, meaning that there are really no magic numbers here. If we add navigation items or change them, this code will be resilient and it will all still work. And if none of this JavaScript runs at all, no big deal. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let&#8217;s look at a cool animated nav effect (from a recent post by Emil Kowalski) that uses CSS `clip-path` to move the highlighted nav item around. It&#8217;s an interesting look at this CSS feature and adds a lot of polish to a simple idea.<\/p>\n","protected":false},"author":1,"featured_media":3114,"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,216,7],"class_list":["post-3103","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-animation","tag-clip-path","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-23-at-10.28.57%E2%80%AFAM.png?fit=1442%2C938&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/3103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=3103"}],"version-history":[{"count":3,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/3103\/revisions"}],"predecessor-version":[{"id":3118,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/3103\/revisions\/3118"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/3114"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=3103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=3103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=3103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}