A Few Interesting Ways To Use CSS Shadows For More Than Depth

Category Image 052

The world of post-modern web design is one where the light doesn’t cast many shadows. That doesn’t mean CSS shadows are going away. On the contrary, they’ve become more adaptive. Shadows are an incredibly useful design element. We know they add depth to an otherwise two-dimensional web design, but did you know we can stack, animate, and manipulate them in ways that go beyond that?

I’ve been experimenting with shadows. In this article, I’m going to share several “tricks” I’ve discovered along the way and how they can be used to create interesting effects that have little to do with their primary role of adding depth. We’ll look at an effect that works by stacking layers of shadows that transition on hover. After that, I will show you how to make a shadow of a shadow. Lastly, we’ll play with shadows on text as an alternative to color.

Ready for some fun? Let’s start with an interesting hover effect.

The Introspective Shadow Hover Effect

Most of us are familiar with the inset keyword. It’s an optional value of the CSS box-shadow property.

When inset is specified, the shadow is cast inside the element, directed inward. It’s commonly used to make it look as if an element has been stamped into the surface of the web page. We are going to push that shadow further, both metaphorically and literally, to create an overlay hover effect for image transitions.

Just as we can control the shadow’s blur radius — how far the shadow spreads outward — we can choose to apply no blur at all to the shadow. We can combine that with the fact that inset shadows are painted over an element’s background (unlike default shadows that are cast beneath the element) to create what I call a “veil” that sits on top of an element.

Let’s start with a single div in the HTML:

<div class="item"></div>

There’s nothing to see yet. So, let’s add some dimensions, a background color, and a border radius to make a green circle.

.item {
  width: 250px;
  height: 250px;
  background: green;
  border-radius: 50%;
}

This is nothing fancy so far. I merely want to demonstrate that we can essentially cover the green background with a red inset box-shadow:

.item {
  width: 250px;
  height: 250px;
  background: green;
  border-radius: 50%;
  box-shadow: inset 250px 250px 0 red;
}

Now we have a red circle with a green background beneath it. We can remove the red inset shadow on hover to reveal the green background:

.item:hover {
  box-shadow: none;
}

See the Pen Inward Shadow Pt. 1 [forked] by Preethi Sam.

Since shadows can be layered and are supported by CSS transitions, let’s incorporate that for a more fluid design. First, I’m going to update the HTML a bit by adding a span inside the .item:

    <div class="item">
      <span>The New York Times</span>
    </div>
    <!-- more items -->

For the CSS, it’s the same idea as before. We want a circle with an inset shadow and a background:

.item {
  width: 300px;
  height: 300px;
  background-image: url('nytimes.svg');
  border-radius: 50%;
  box-shadow: inset -300px -300px 0 black,
}

The difference so far is that I am using a background-image instead of a background-color. They are absolutely interchangeable for the hover effect we’re working on.

Next, I’m going to do two things. First, I’m going to stack more inset shadows inside the .item. Then I’m changing the text color to white, but only for a moment so the background image shows all the way through.

.item {
  width: 300px;
  height: 300px;
  background-image: url('nytimes.svg');
  border-radius: 50%;
  box-shadow:
    inset -300px -300px 0 black,
    inset 300px -300px 0 green,
    inset -300px 300px 0 blue,
    inset 300px 300px 0 yellow,
    0 0 20px silver; /* standard outset shadow */
  color: white;
  }

Even after we add those four extra shadows, we still are left with only a black circle that says “The New York Times” on it in white. The trick is to remove those shadows on hover, change the color of the text to transparent, and reveal the logo beneath our stack of inset shadows.

.item:hover {
  box-shadow:
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    0 0 20px silver; /* retain the outset shadow */
  color: transparent;
}

That works! But perhaps we should add a little transition in there to smooth it out:

.item {
  width: 300px;
  height: 300px;
  background-image: url('nytimes.svg');
  border-radius: 50%;
  box-shadow:
    inset -300px -300px 0 black,
    inset 300px -300px 0 green,
    inset -300px 300px 0 blue,
    inset 300px 300px 0 yellow,
    0 0 20px silver; /* standard outset shadow */
  color: white;
  transition:
    box-shadow ease-in-out .6s,
    color ease-in-out .5s;
  }

.item:hover {
  box-shadow:
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    inset 0 0 0 transparent,
    0 0 20px silver; /* keeping the outset shadow */
  color: transparent;
}

The only other thing I think that’s worth calling out is that the outward shadow in the stack is not removed when the .item is hovered. I only want to remove the inset shadows.

Here’s the final result:

See the Pen Inward Shadow Pt. 2 [forked] by Preethi Sam.

I used CSS variables throughout so you can change the colors of the shadows and the size of the element.

Casting A Shadow Of A Shadow

If we learned anything from that last example, it’s that shadows are visually interesting: they can bend, fade, intersect, and transition. But what about a shadow casting another shadow? Can we create a shadow of an element’s shadow?

This is not the same as stacking layers of shadows as we did earlier. Rather, we will be making a silhouette of a shadow. And because we have a second way to add shadows to elements with the CSS drop-shadow() filter, we can do exactly that.

A drop-shadow() is a little different than a box-shadow. Where a box-shadow casts a shadow along the physical edges of the element’s bounding box, a drop-shadow() ignores the box and casts a shadow along the element’s shape.

When drop-shadow() is given to an element with a box-shadow, the shadow from the box-shadow will cast a shadow of its own. We can combine these to make interesting effects, like a Venn diagram shape.

.item {
  box-shadow: 0 0 20px black ;
  filter: drop-shadow(-30px 0 0 blue);
}

See the Pen Shadow of a Shadow Pt. 1 [forked] by Preethi Sam.

This simple combination of box and drop shadows can lead to interesting designs, like shadows that cast shadows. Let’s start with some HTML that includes the same .item element we used in the last section. This time, we’ll place two child elements inside it, another div and an img:

<div class="item">
  <div class="background"></div>
  <img src="image.jpeg" />
</div>

<!-- more items -->

The .item is merely serving as a container this time. The real work happens on the .background child element. The image is purely there for decoration. We’re going to set a box-shadow on the .background element, then add a stack of three drop-shadow() layers to it:

/* third circle in the following demo */
.item > .background {
    box-shadow: 0 0 40px rgb(255 0 0 / .5);
    filter:
      drop-shadow(-20px 0 0 rgb(255 0 0 / .5))
      drop-shadow(20px 0 0 rgb(255 0 0 / .5))
      drop-shadow(20px 0 0 rgb(255 0 0 / .5));
}

We can also use transitions with these effects (as in the middle circle below).

See the Pen Shadow of a Shadow Pt. 2 [forked] by Preethi Sam.

The Textual Shadow

The last effect we’re going to look at involves the CSS text-shadow property. It’s actually less of a complicated “trick” than it is a demonstration of using and showing just the shadow of a text element for color purposes.

Specifically, I’m talking about transparent text with a shadow on it:

/* second column in the below demo */
p {
  color: transparent;
  text-shadow: 1px 1px 0 black;
}

See the Pen Textual Shadow Pt. 2 [forked] by Preethi Sam.

Notice the emoji? Instead of the full-color deal, we normally get, this emoji is more like an icon filled with a solid color. This is one way to make a quick and dirty icon system without drawing them or working with files.

We could have also pulled this off with background-clip: text to clip around the shape of the emoji or apply a drop-shadow(). However, that affects the background, limiting where it can be used. Plus, I like the idea of using text-shadow with text elements since that’s what it’s used for, and emoji are part of the text.

You might think there’s a “gotcha” with underlines. For example, text-shadow ignores the text decoration of links.

See the Pen Text Shadow No Likey Link Underlines [forked] by Geoff Graham.

No big deal. If you need to support underlines, we can reach for the CSS text-decoration and text-underline-offset properties:

p {
  color: transparent;
  text-shadow: 1px 1px 0 black;
  text-decoration-line: underline;
  text-decoration color: black;
  text-underline-offset: 3px;
}

See the Pen Shadow-Only Link With Underline [forked] by Geoff Graham.

Conclusion

That’s a look at three interesting ways to use CSS shadows as more than that thing you use to add depth. We looked at one way that uses inset shadows to hide the contents of an element’s background for a neat hover effect. Then there was the idea of combining box-shadow and drop-shadow() to cast a shadow of another shadow. We capped things off with a quick way to manipulate text and emoji with text-shadow.

I hope these experiments give you the inspiration to do some CSS shadow experiments of your own. Shadows and gradients are perhaps the two most important CSS features for “drawing” with CSS, like many of the examples you’ll see on Lynn Fisher’s A Single Div project. Shadows have incredible browser support, so the options are plentiful as far as what we can do with them.

Further Reading On SmashingMag

Me, a Conference Speaker? Yes, You!

Featured Imgs 23

I have been in your shoes: it is very intimidating to get in front of strangers and speak about your passion: technical topics where others are stronger; opinions that are the anthesis of commonly-held beliefs; real-life solutions which you don’t believe are that unique. Or perhaps the most scary: people get bored and walk out on you.

Yet, how many conference sessions have you attended or watched webinars where you thought I knew this, I know more than the speaker, or even I totally disagree, and here’s why. The speakers you enjoy listening to — the David Belvins, Holly Cummings, Trisha Gee, Josh Long, Reza Rahman, Venkat Subramaniam of the world, and many others — started simply: likely pushed, goaded, and mentored into speaking. Practice and experience — and likely multiple failures — help novice speakers into rock stars.

The Evolution of Continuous Merge

Featured Imgs 23

On this week’s episode of Dev Interrupted, co-host Conor Bronsdon and Ben Lloyd Pearson, LinearB’s Director of Developer Relations, detail the evolution of Continuous Merge and the tool behind it, gitStream. Joining the conversation is Nik LeBlanc, VP of Engineering at DevCycle. 

Nik shares the ways his team is using gitStream to streamline code reviews and offers practical advice for anyone looking to implement the tool on their own team. He also explores the somewhat controversial practice of splitting up and reshuffling engineering teams, a strategy that DevCycle has used to great effect. Nik finds that this practice helps balance teams, manage diverse knowledge bases, and de-risk the organization.

Chris Corner: The Tao of Demos¹

Category Image 052

CodePen is a place where you can make demos. A Pen can be anything (a painting, a game, a landing page), but by and large, Pens today are demos. Why would you make a demo? Fam, why wouldn’t you make a demo? Demos are one of the most powerful tools we have as designers and developers. But the reason behind making one can be very different. That’s why it always made it hard for me to elevator pitch CodePen: I’d want to list a dozen reasons you’d want to use it, and I’d come across as unfocused. Well, too bad. I like that there is lots of reasons to use CodePen and make demos.

Let’s make an incomplete list of reasons to build a demo:

  • Prove something to yourself. You’ve seen a new library, a new web platform API, or just some kinda something you wanna try. It’s one thing to read a little something about it. That’s good, it helps you slot the [new thing] into some brain bucket where you might be able to find it later. But does it really do what you think it does? Does it? Really? Prove it with a demo.
  • Get everyone on the same page super quickly. I was just in a meeting the other day where a teammate of mine highly encouraged the meeting to start with the design comp. We actually had planned it the other way around. We wanted to go over the requirements and take a look at how the data structures were coming along, then see if the early design was on target. But after switching that up to see the design first, it immediately got everyone engaged and thinking about the same thing. How it ends up on the page is the end goal, after all. There is something about interactive visuals that gets everyone perked up. Come to that next meeting with a demo.
  • Demonstrate a concept in the most minimal way possible. If you’re trying to learn or teach something, removing the extraneous can be an effective way to focus on the core idea. Contextual demos are useful later once the ultra-focused demo has made its point. For example, see how effective Gabi’s Flexbox Playground is. After you understand that core concept, then you can move on to real-world usage.
  • Do it in a sandbox. The concept of a sandbox is usually referencing security. It’s a safe place where you can’t screw up. Cool; useful. But it also can imply that it is untethered. Like prototyping a component without the baggage of the rest of the site. Doing work free from the usual constraints can be freeing — you might think of things you wouldn’t have otherwise.
  • Help fix someone’s bug or help them fix their problem. When someone is stuck while coding, answering them with code is the best. You aren’t just running your mouth, you’re putting money in it. There is a lot of good karma to be had here — answering a question or fixing a bug with a public demo will help that person today, and more people tomorrow.
  • Whimsy. A coding job can be awfully serious. You’re doing important work. Work that affects people’s lives with things they are trying to do. You should take that seriously. But that doesn’t mean everything you do has to be so sober. Get loose. Get weird. Shake it up. Let it all hang out. Code doesn’t always have to be useful. A freaky demo might be just the catharsis the doctor ordered.
  • Build a variation on something. Great artists steal, they say. Grab it, tweak it, make it yours. Could be anything you see on the internet (I use the browser extension CSS Pro to do this sometimes: with it, you can select an element and click a button to whisk it over to CodePen with all the HTML and CSS intact). From a design systems perspective, component libraries are most useful when they have variations you can choose from that serve the needs of anyone using the system.
  • Relax. People like to knit, ya know. And crochet and cross-stitch and sew. Oh, and do crosswords and su-do-ku and that game where you spot the differences across two images. Those things require your brain to be turned on a little bit, but it’s still relaxing. It’s not weird to relax by building a little demo just for the fun of it.
  • Nothing shows you care more than a reduced test case. If you need help with code, the best thing you can possibly do is showcase your problem with as little in the way as absolutely possible. Strip away unrelated code as much as you can. Not only might you solve the problem yourself that way, anyone looking to help will be appreciative that you’re respecting their time.
  • Show off. The kids call it flexing, I think. Make something so cool people just have to stop and look. Everybody deserves a little vanity. You know plenty of people have gotten jobs based on demos they’ve made on CodePen, right? It’s true. Show the world what you can do.
  • Treat it like school. The secret goal of schools is getting you to learn how to learn. I’ll break it to you: if you’re building demos of your own volition outside of an educational context, school worked on you. Good on ya. If you wanted, you could work through a curriculum building code demos. That’s basically what coding schools are.
  • Test something. Does it work how you think it does? Is it actually possible? How do you know if it works if you don’t test it? And equally important: is it worth it?
  • Prep a hiring exercise. Live coding interviews are a little controversial, but asking someone to demonstrate that they can do the job of design and/or development during the hiring process for a job that is design and/or development is a good idea. Perhaps it’s an async thing. How much would you learn about someone if you asked them to think out the considerations around a hamburger menu? What if you asked someone to spend two hours building a tic-tac-toe game playable across two browser tabs using web sockets?
  • Write some code you know doesn’t really matter. There is a good chance you got into this field because you like code. A demo you know you’re going to throw away is proof you still like that journey. You’re a musician taking pleasure in practicing some scales.

If you look at all the wonderful demos above in this very newsletter, some of them will have been created for some of these reasons. But honestly, most demos are a little more throw-away than the ones that make it into The CodePen Spark. You’ll have your own reasons.

I was thinking about all of this after reading Andy’s The art of the demo, which starts:

Nothing enhances written content quite like a well-crafted demo, or collection of demos. They don’t have to be complex either — in fact, it’s better if they’re not complex. The most important thing is that good quality demos can help people really get what you’re trying to explain, especially if reading isn’t the most effective way for them to learn.

❤️


¹ Demtaos? Nah.