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

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.

Chris’ Corner: Useful HTML and CSS Patterns

Category Image 052

The <table> is one of the grand enemies of responsive design. They don’t wrap (that wouldn’t make much sense) so they can “blow out” the width of a mobile device pretty easily. The overflow property also doesn’t work on them. So you gotta find a way, and it really depends on the data. Sometimes a row of table data is pretty independently useful (imagine a row of employee data) so making all the <tr> and <th>/<td> element display: block and stacking them works. But that doesn’t work for data that needs to be cross-referenced. I think there are 3-4 other patterns that involve shuffling the data around to be more narrow-screen friendly. The old group of jQuery plugins Tablesaw from Filament Group showcase some of them.

Lately, I find rather than dig around for a display-altering solution, people just wrap the table in a <div> and let that <div> have overflow. So now you’ve got a table that you can scroll/swipe around without really changing how the table looks. I find myself consulting Under-Engineered Responsive Tables by Adrian Roselli on how best to do that regularly.

Ryan Mulligan has a cool take as well in Full-bleed Table Scrolling on Narrow Viewports. The “full bleed” part means using the edge of the browser window. Which you might otherwise not! Typically there is padding on the left/right (“inline”) edges of content, which would also be limiting the width of the table.

Demo

The blue line in the screenshot above shows the padding on the column of content, which limits the width of the content inside there, but the table is explicitly pulled out from it to the edge. It’s a little thing but it’s classy!


Josh Comeau’s tutorial Animated Pride Flags has lots of fun things to learn along the way of creating a controllable version of this:

Notice that staggering is a big part of the look here. That happens with slightly different values to animation-delay. Since Josh used React to created the DOM for this, the loop can output those values as inline styles and use the number of iterations that map provides to stagger the value.

But wait! Maybe CSS should be helping us here, rather than us having to invent our own way to stagger things, right? That’s what the sibling-count() and sibling-index() proposal is all about. I’m a fan.

Josh’s tutorial basically just starts here and then covers more and more details. I especially like the bits of also stagging how much any given column “billows”, which is another use-case of staggering a custom property value. Also don’t miss the bits about double-stop color gradients and rounding width values to prevent awkward pixel gaps.


How should I mark this up? is always fun trivia. For me, anyway, I’m a very exciting person. Sometimes HTML has pretty cut-and-dry right and wrong ways to do things, but sometimes it doesn’t. There are differents ways with styling tradeoffs, accessibility tradeoffs, amount of markup tradeoffs, etc.

Lea Verou found a good one in What is the best way to mark up an exclusive button group? In other words, a group of buttons where only one can be active at a time. A multi-toggle? Lea, and plenty of other people, assumed that a group of <input type="radio"> is the right answer (only one radio button can be active at once), and then style them like buttons. I thought about <select> too which can only have one active choice, but no way are you going to be able to style that as buttons, even with the wildly more styleable <select-menu>.

Léonie Watson stepped in with advice that essentially boiled down to: if they look like <button>s, you should use <button>s, so there isn’t “a mismatch of expectations in terms of keyboard interaction and shortcuts.” Interesting!

Lea thinks maybe we need a <button-group>. Again, I’m a fan. I would have even kept <hgroup> around, me, for grouping multiple headers.


Have you heard this (correct) advice? Placeholders aren’t labels. Like, don’t do this:

<input type="text" placeholder="Your Mastodon Profile" />

Do this:

<label for="mastodon-profile">Your Mastodon Profile</label>
<input type="text" id="mastodon-profile" placeholder="https://fosstodon.org/@codepen" />

A placeholder can be a little bonus hint or something, but even then, if that hint is important it should be accessible text which placeholder text is not.

I’m thinking of that because I saw Stanko Tadić’s CSS only floating labels. Floating labels is a pattern where text that looks like placeholder text (text within the input) moves away from the input but remains visible. This has gotten a bit easier as of late with the :placeholder-shown pseudo-class.

Demo

What I like about the floating label pattern is that it continues to use <label>, so the accessibility remains. It’s also just kind of clever and fun. What I don’t like about it is that I don’t think it does anything truly useful. I’ve heard proponents of it say that it “saves space” because the label is inside the input. But it’s only inside the input until it’s focused, then it moves out, and it moves out to somewhere where it needs to remain visible and have space. So……… why don’t you just put the labels where they move out to in the first place? Kinda feels like movement, for movement’s sake.


If you haven’t tried to create a password with Neal Agarwal’s * The Password Game yet, you really should give it a crack.

Lol. And there is plenty to go even after this stage.

Chris’ Corner: Clever CSS Ideas & Explanations

Category Image 052

If you think frosted glass effect in CSS, you probably think of the backdrop-filter property. Just backdrop-filter: blur(10px); will do the trick. I still think the look is kind of cool and fresh, but I should check myself a little here as the effect was popularized in the iOS 7 release which was 10 years ago 🫠.

Here is a fresh take though: Frosted Glass: Depth-based blur in CSS (make sure to mouse around to see the dynamic effect, and scroll down to see the effect on different backgrounds).

The how-to is that layered blurs are masked and the mask moves with the mouse. I love clever stuff like that, which ends up fairly simple.


The above demo is a nice demonstration of masking, actually, because it’s doing something that is uniquely mask-y: using a gradient. The other concept that can cut out parts of something is a clip-path, but with a clipping path, any given part of an element is either clipped or not, whereas with a mask, an area can become partially transparent.

Ahmad Shadeed has a recent article on CSS Masking that does a good job of explaining how it all works and what you can do with it.


There is this little design concept that if you have nested elements that both have border-radius, they can’t have the same border-radius otherwise they tend to have a weird little hump in the middle and essentially just look off and not particulary professional. I wrote about this in 2011 and have had many people thank me over the years! (not that I’m the first.)

The general thinking is that you subtract one from the other, and it comes up from time to time. Adam Argyle recently noted that there is a way to solve this with no math at all, but it’s Chrome-only at this time.

This uses overflow: clip; and overflow-clip-margin: content-box; which this is the first I’m hearing of the latter! I like it!


I feel like we’re doing a good job of talking about paths this week so lemme slip another one in here: Jhey’s Circular Text with CSS?. To be clear: there isn’t a normal first-class CSS citizen kinda way to say “set this text on this path”. Unless that path is a straight line, I suppose. SVG has the <textPath> element and that’s really what you want here if you’re going to this even semi-seriously. But there is some trickery to be had here!

This makes me feel like Captain Old again saying I wrote about this in 2012, but here we are. The trick then was to break the text into individual character <span>s and then transform them all around a shared origin:

Jhey’s idea still uses a monospace font and breaking the characters up into spans, but there is more clever math involved. He’s got it set up so however many characters you use, the complete one full circle no matter what. The secret is trigonometric functions, which are only freshly available in CSS. Plus he took the time to make sure there is screen-reader-friendly text in there too, as text-as-spans is a nightmare that way.


If you read all the stuff above and felt some version of ughkg CSS is so hard, maybe you’ll find some solace in Mike Aparico’s Why we’re bad at CSS. Part of Mike’s point is that CSS gets harder the more you try to avoid it, or apply abstractions that are too heavy-handed.

We want our styles to be generic enough to reuse in different contexts but not so generic that we have to constantly repeat ourselves in those contexts.

I feel like there is a tendency for people who feel like they have a handle on CSS to have essentially invented their own methodology (whether they choose to share it or not). That might seem like a failing of CSS or something that you need to invent your own system to be effective with it, but ultimately I think that’s true of any language. You build up your own ways of doing things that works for you and run with it.

Chris’ Corner: Hot New Web Features

Category Image 052

Yuri Mikhin and Travis Turner over at Evil Martians implore us: Don’t wait, let’s use the browser Contact Picker API now. As I write, it’s only available essentially on Chrome for Android. But the spec exists and iOS also has an experimental flag for it. I’m an iOS guy so I flipped it on. I actually didn’t even know you could do that! (Settings > Safari > Advanced > Experimental Features).

You can see the contact picker in there and other cool stuff like text-wrap.

Now if you’re in a browser that supports it…

The select method will show users a modal UI to select contacts, and it will then return a Promise. If the promise resolves, it will return an array (even if only one contact was selected) filled with ContactInfo interfaces.

I’m sure you can imagine it. You tap a button or something, and it launches a contact picker. You select a contact from your device’s contacts. It returns data from those contacts, like names, emails, and phone numbers.

Not every app needs it, but I imagine a lot could make use of it (particularly in a progressive enhancement style). Does your app have any kind of invite or sharing UI? You could use it there. I’m thinking of something like Figma’s share modal:

I’m just on my own to write in email addresses in there. If this was Google Docs, well, they have the distinct advantage that they already have a contact list for you thanks to the likelihood that you also use Gmail and keep some form of your contacts there. But very few of us are Google. The Contact Picker API levels that playing field!

I gave the Evil Martians demo a spin, and it works great.

Weirdest part? No “search” ability in the contact picker popup.

If there were only some kind of easy-to-use web app that makes it really easy to play with new APIs like this and get a feel for them and save them for later reference. Some kind of playpen for code.


I think I was bitching about text-wrap: balance; the other day. Just like me, to be given such a glorious new property that helps makes headlines look better across the web and find something to not like about it. The balance value takes multi-line text and makes all those lines as roughly even as it can. I feel like that looks pretty good for headlines, generally. The kicker is that “balancing” isn’t always what people are looking to achieve, and what they really want is just to avoid an awkward orphan single word from wrapping down onto the next line.

Adam Argyle said to me: have you seen text-wrap: pretty;?

  1. No, I have not.
  2. Awww, pretty is a great keyword value in CSS.

I googled it and found Amit Merchant’s quick coverage. Then I set about making a demo and trying it out (only works in Chrome Canary until 117 ships to stable).

See what I mean about balance above? There is just far too much space left over above when all I really wanted to do was prevent the single-word orphan. Now pretty can prevent that.

That’s so generically useful I might be tempted to do something like…

p, li, dt, dd, blockquote, .no-orphan {
  text-wrap: pretty;
}

… in a “reset” stylesheet.


People reflecting on formative moments in their lives usually makes for a good story. And especially relatable when they are like: “… and that’s how I became a nerd.” That’s what happened when Alexander Miller’s dad gave him some paper:

When I was a kid, my dad gave me a piece of paper with a grid printed on it. It consisted of larger squares than standard graph paper, about an inch in size. It was basically a blank chessboard.

GRID WORLD

I didn’t become an incredible code artist like Alexander, but I can still relate. My first really “successful” programs were grid-based. First, a Conways’ Game of Life thing (that I’m still a little obsessed with) and then a Battleship clone (like Alexander’s father). These were absolutely formative moments for me.


Do you know one of the major JavaScript frameworks better than another? I bet you do, don’t you? You’re a Svelte groupie, I can tell.

Component party is a website that shows you how to do the basic and important stuff in each major framework (React, Svelte, Vue2/3, Angular, Lit, Ember, and several more). Very clever, I think! It’s helpful to know one of the frameworks so you can verify that’s how you would have done it there, then see how it works in another framework. Like if you need to loop over data in React, you probably end up doing a .map() thing, but in Svelte there is #each, where in Vue it’s a v-for attribute. I don’t work across different frameworks enough to have all this memorized so a big 👍 from me for making a useful reference here.


“Sometime this fall (2023)” is all we know for the release date of macOS Sonoma. Normally operating system releases aren’t that big of a deal for web designs and developers, who are more interested in browser version releases. But Sonoma has a trick up it’s sleeve.

With macOS Sonoma, Apple goes all-in on the concept of installable web apps. They’re highly integrated in the overall macOS experience and don’t give away their web roots by not showing any Safari UI at all.

Thomas Steiner, Web Apps on macOS Sonoma 14 Beta

Installable web apps, you say? Like… PWAs? (Progressive Web Apps). The point of PWAs, at least in my mind, is that they are meant to be real competitors to native apps. After installation, they are clickable icons right there next to any other app. Level playing field. But to become installable, there was kind of a minimum checklist of requirements, starting with a manifest.json.

The word from Apple is that there are literally zero requirements for this. You can “Add to Dock” any website, and it’ll work. I guess that means it’s possible to have a docked app that just entirely doesn’t work offline, but 🤷‍♀️.

Sites installed this way do respect all the PWA mechanics like one would hope! Sites with a manifest won’t show any Safari UI at all. I don’t think there are install prompts offered yet, so users would have to know about this and/or find the menu item. There are prompts though in regular Safari if users go to a website that is already installed (to “Open” the “app”).

Overall, apps installed this way look pretty nicely integrated into the OS. But I also agree with Thomas’ wishlist, all of which seem like they would make things much better still.

How to Hide Page Titles in WordPress: 4 Easy Methods

Category Image 052
how to hide page titles in WordPress.Want to learn how to hide page titles in WordPress? Although WordPress does not offer a native feature to hide page titles, you have plenty of options to get the job done, including both code-free options and custom CSS. In this article, you’ll learn four methods that you can use to hide the title for individual pieces of content or for all of your content:

Redefining Element Positioning With CSS Inset Property

Category Image 052

Building responsive web pages is essential if you want your website to run flawlessly on multiple browsers without hiccups. However, websites can’t be fully responsive without a proper layout. Here the CSS position property lets you do this.

The CSS position properties set a specified element relative to its parent or the viewport. The CSS position properties take in five values, namely,

Chris’ Corner: Design

Category Image 052

Rauno Freiberg wrote an article getting into the CSS implementation of some of the neat features of the most recent Next.js website. Gotta love an article showing off how things work on a really top-notch modern design. Thoughts as I go down the list:

• The randomized dots on the switchboard look super cool. Just a tiny little box-shadow does the trick, but they need to be animated with opacity because animating opacity is super performant and animating box-shadow is very not. I wonder if we’ll ever get past gotchas like that? Also, the dots aren’t exactly random, they are just placed seemingly-randomly. What if we had real randomization in CSS? It’s been being talked about again seriously.

• The offset focus styles were done with a box-shadow. It was noted that outline now follow border-radius across the board, which opens up that door, and is powerful thanks to outline-offset. I think I would have gone with outline-offset because I like thinking about how easy that is to control. One example: if you find that your focus styles are getting cut off by hidden overflow, you have the option to use negative offset to pull the focus styles inside where they won’t get cut off instead.

• To pull the quotation marks of a blockquote toward the inline direction a bit, lining up the words, a bit of negative text-indent was used. That’ll work cross-browser, but it’s a shame we have to rely on a magic number rather than the purpose-built hanging-punctuation property. Let’s root for better support there.

• Love to see that fluid type in action! I see the blog post is using clamp() with a viewport unit. I’d recommend making sure that middle parameter factors in a little rem unit of some kind so that user font sizing is honored. The production website actually uses max(48px,min(5vw,76px)) and I’m curious about the change there. Seems… the same? And actually, since I bet the headline is an isolated React component, it’s kinda begging for the whole thing to be a container and for the header sizing to be done with a cqi unit instead.

• The “gradient tracking” trick using a moving SVG gradient background is just incredibly cool and absolutely one of the nicest effects I’ve seen anywhere this year. 5 stars.


I did a talk somewhat recently called “Modern CSS in Real Life,” and now I’ve turned it into a blog post in case digesting it that way is of interest to you.

One of the things I dwell on in the beginning is the use of Logical Properties in CSS and how you get some nice benefits out of using them. One is that I think it very slightly makes CSS easier to reason about. But the bigger one is that it helps a site that is being auto-translated behave better. In particular, I showed off an article that would have ended up mucher nicer when being translated from the Left-to-Right English default to Right-to-Left Arabic.

I thought of that again the other day as I came across the Arabic Design Archive. It’s interesting to look at designed items that need both language directions at the same time.

I like how the main thrust of the design is RTL, forcing the English headline to be right-aligned, but still looks great. Then in the smaller and slightly longer text, both directions are accommodated nicely by that vertical bar which both inline directions butt against.

Oh and speaking of design archives… archive.design is:

A digital archive of graphic design related items that are available on the Internet Archives

Chris’ Corner: Scoping

Category Image 052

If I were going to argue against @scope, the new CSS feature, I might say that CSS already has scope. Like, every selector is “scope”. If you say .el, you’re saying “scope this bit of CSS to elements that have the class name of ‘el'”. But then someone might tell you, ok, but what about “donut scope” 🍩? Donut scope is a way for a scope to stop. Keith Grant shows that off in a recent article:

@scope (.card) to (.slot) {
  /* Scoped styles target only inside `.card` but not inside `.slot` */
  :scope {
    padding: 1rem;
    background-color: white;
  }

  .title {
    font-size: 1.2rem;
    font-family: Georgia, serif;
  }
}

Imagine that applied to this HTML:

<div class="card">
  <h3 class="title">Moon lander</h3>
  <div class="slot">
    <!-- scoped styles won’t target anything here! -->
  </div>
</div>

I’m not sure how I feel about that, honestly. Don’t hate it, but also can’t think of a time when I really really wanted that. That might be because it’s never existed so my brain didn’t try to reach for it. But container queries didn’t exist before, either, and I think we all pined for those anyway. Still, it’s a bit of a +1 for @scope because it’s a thing we can’t do any other way.

If I was still arguing against @scope, then I’d say, well, it turns out actually you can replicate donut scope, thanks to another modern CSS feature, :has(), as Bramus blogged:

.from ~ :has(~ .to) {
  outline: 1px solid red;
}

And actually, you don’t even need that.

So I’m afraid I have to rescind the point I gave @scope. Are there any other tricks up its sleeve? It does have one! It’s called proximity. This is just kind of a bummer situation in CSS:

<div class="green">
  <p>I’m green</p>
  <div class="blue">
    <p>I’m blue</p>
  </div>
</div>

If you wrote the CSS like this:

.blue p {
  color: blue;
}
.green p {
  color: green;
}

Then both paragraphs are green. Just because the green selector came second. That’s just how CSS selectors work. Both have the same specificity so the latter one wins. We can fix this with scopes:

@scope (.green) {
  p {
    color: green;
  }
}

@scope (.blue) {
  p {
    color: blue;
  }
}

Now that second paragraph is properly blue because the closer scope wins (and it doesn’t matter what order they are in). This is nice for color theming when you use classes to change the theme “higher up” in the DOM. But it doesn’t save you from increased specificity of other selectors, which are probably a more common “bug”. Still, I’ll say this is worth a +1!

Still, I’m not salivating for @scope. It doesn’t solve any big pain points that I’ve personally had. But maybe it does for you, the web is a big place, so all good.

I’ve said it before, but I think the super old-school idea of wanking a <style scoped> into the DOM anywhere and having those styles scoped to the parent is still a cool idea and actually does solve problems. Coupled with :scope { } it means I don’t even have to think of a name of how to select an element, yet still get the ability to apply pseudo-elements and the like. So inline styles with more abilities. And without having to name anything, there is no possible way for the styles to leak anywhere else. Sure, it’s neat to stop style leaking with a @scope too, but because I have to apply it to a class, I need to make a super obscurely named class like .card_987adf87d (a build tool concern) for it to actually worry-lessly “scope”.

The post Chris’ Corner: Scoping appeared first on CodePen Blog.

How to Use Shortcodes in your WordPress Sidebar Widgets

Category Image 052

Do you want to learn how to use shortcodes in your WordPress sidebar widgets?

You can add shortcodes to any page or post using the Shortcode block. However, if you want to use the same code across your entire site then it may be easier to add it to a sidebar widget instead.

In this article, we will show you how to use shortcodes in the WordPress sidebar.

How to use shortcodes in your WordPress sidebar widgets

Why Use Shortcodes in Your WordPress Sidebar Widgets?

Shortcodes allow you to add advanced content and features to your website, including contact forms, tables, random quotes, and much more. WordPress comes with several built-in shortcodes but some plugins also add their own shortcodes.

You can add shortcodes to any page or post using the WordPress editor and built-in Shortcode block. However, if you want to use shortcode across your entire site then it often makes sense to add it to the sidebar.

For example, you can display Instagram photos in the WordPress sidebar using a shortcode provided by Smash Balloon Instagram Feed.

An example of a social media sidebar widget

This content will then appear across your entire WordPress website, so you don’t need to add it each page and post manually. This can save you a ton of time and effort, and helps to keep your site’s design consistent.

With that in mind, let’s look at a few different ways to add and use shortcodes in the WordPress sidebar widgets. Simply use the quick links below to jump straight to the method you want to use.

Method 1: Using the WordPress Shortcode Widget (Easy)

Most free and paid WordPress themes come with widget-ready sidebars. With that in mind, you can often simply add a Shortcode widget to your website’s sidebar.

First, go to Appearance » Widgets in your dashboard. Here, you’ll see all the different areas where you can add widgets in WordPress, including the sidebar.

Adding a shortcode widget to a WordPress sidebar

Simply click on the ‘+’ button and start typing in ‘Shortcode.’

When the right block shows up, drag it onto the WordPress sidebar.

How to add a shortcode to the WordPress sidebar

You can now add your shortcode to the block.

When you’ve finished, don’t forget to click on ‘Update’ to make the changes live.

Publishing a shortcode block in WordPress

You can now visit your WordPress blog or website to see the shortcode in action.

Method 2. Using the Full Site Editor (Works With Block-Enabled WordPress Themes)

If you’re using a block theme then you can add shortcode to the sidebar using the full-site editor. In your WordPress dashboard, go to Themes » Editor.

Opening the WordPress full-site editor (FSE)

This opens the full-site editor, with one of your theme’s templates already selected.

If you want to add shortcode to a different template, then click on the arrow in the toolbar and select ‘Browse all templates.’

Choosing a block-based FSE template

You’ll now see all the different templates that make up your theme.

Simply find the template where you want to add the shortcode, and give it a click.

A block-based WordPress theme

After that, click on the ‘+’ button and start typing in ‘Shortcode.’

When the right widget shows up, simply drag it onto the theme’s sidebar.

Adding a WordPress block to the sidebar

You can now add your shortcode to the widget. When you’re happy with your changes, click on ‘Save’ to make the shortcode live.

Method 3: Using the Custom HTML Widget (More Customizable)

Sometimes you may want to show other content along with the shortcode. For example, RafflePress can add a contest or giveaway to your sidebar using a shortcode. To draw even more attention to the contest, you may want to show a heading above the competition.

An example of a giveaway created using RafflePress

Instead of creating separate Shortcode and Heading blocks, you can simply add the shortcode and text to a Custom HTML block. This helps you arrange the different content in a nice layout. You can also style the block using HTML, so you can control exactly how it looks in the sidebar.

The Custom HTML block doesn’t support shortcodes by default, but you can easily change this by adding custom code to WordPress. After adding this code, you can use shortcodes in any Custom HTML block across your entire WordPress website.

Often, you’ll find guides with instructions to add custom code to your site’s functions.php file. However, this isn’t recommended as any mistakes in the code can cause common WordPress errors, or even break your site completely.

That’s where WPCode comes in.

This free plugin makes it easy to add custom CSS, PHP, HTML, and more to WordPress, without putting your site at risk. Even better, it comes with a library of ready-made snippets including code that allows you to use shortcodes in text widgets.

To start, you’ll need to install and activate WPCode. For more information, you can see our step-by-step guide on how to install a WordPress plugin.

After that, go to Code Snippets » Add Snippet in the WordPress dashboard. You can now start typing in ‘shortcode.’

Adding a code snippet to your WordPress website

When it appears, hover your mouse over the following snippet: ‘Enable Shortcode Execution in Text Widgets.’

You can then go ahead and click on ‘Use snippet.’

Adding shortcode to a custom HTML block using code

This will open the snippet in the WPCode editor. WPCode configures the snippet settings for you, so you can simply click on the ‘Inactive’ switch so that it turns blue.

With that done, click on ‘Update’ to make the snippet live.

Adding shortcode to a sidebar widget using code

Now, you can add a shortcode to any text widget.

Simply go to Appearance » Widgets and type ‘Custom HTML’ into the search bar.

Adding a Custom HTML widget to a WordPress sidebar

When the right block appears, drag it onto your website’s sidebar.

With that done, you can add your HTML and shortcode to the block.

Adding a custom HTML widget to a WordPress website

When you’re happy with how the widget is set up, click on ‘Update.’

Now if you visit your website, you’ll see the shortcode and custom HTML live.

FAQ: Using Shortcodes in WordPress Sidebar Widgets

No matter what theme you’re using, you should be able to add shortcodes to the sidebar using one of the methods above. However, if you need extra help then here are some of the most frequently asked questions about adding shortcodes to the sidebar.

How Do I Change Where the Sidebar Widget Appears?

The sidebar’s location is controlled by your WordPress theme. If you’re not happy with the sidebar’s position then you may be able to change it using the theme settings.

Many of the best WordPress themes let you choose between different layouts. Often, this includes showing the sidebar on different sides of the screen.

To see whether your theme has different sidebar layouts, go to Appearance » Customize in the WordPress dashboard. Here, look for any settings labeled Sidebar or similar.

Changing your theme's sidebar settings

Simply click on this option and look for any settings that allow you to change where the sidebar appears on your site.

For example, the following image shows the sidebar settings in the Astra WordPress Theme.

The Astra sidebar settings

After making your changes, click on the ‘Publish’ button to make the new sidebar layout live.

If you can’t change the sidebar’s location using the built-in settings, then another option is to create a WordPress child theme.

How Do I Add a Sidebar to My WordPress Theme?

If your theme doesn’t have a sidebar then you could create a child theme and then add a sidebar using code.

If you’re not comfortable writing code, then you can also create a custom WordPress theme using a plugin such as SeedProd. You can use this popular page builder plugin to design your own theme and sidebar using a simple drag-and-drop editor.

For step-by-step instructions, please see our guide on how to create a custom WordPress theme without any code.

How Do I Use a Different Shortcode on Each Post or Page?

Sometimes you may want to use different shortcodes on some of your posts and pages.  For example, you might want to show the most popular posts on your archive page and display ads on your homepage.

To learn more, please see our guide on how to display different sidebars for each post and page in WordPress.

We hope this article helped you learn how to easily add shortcodes to your WordPress sidebar widgets. You may also want to see our guide on how to create a landing page with WordPress or our expert pick of the best social media plugins.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Use Shortcodes in your WordPress Sidebar Widgets first appeared on WPBeginner.

Chris’ Corner: A Balancing Act

Category Image 052

If you’re a super normal person like me, you’ve gone to war with typographic widows and orphans many times over your years as a developer, trying to ensure they don’t happen and ruin anyone’s day. You know what I mean, a headline with one silly little word that has wrapped down onto its own line. If only you could add a couple of soft returns in there to prevent it. You can, of course, but you know better. A soft return might fix a problem at one particular container width, that break causes an even more awkward problem at another container width.

One technique that is sometimes employed is to insert a &nbsp; (non-breaking space) between the last two words (maybe even three?) of a headline (or paragraphs, if you’re nasty).

This little piggy went to&nbsp;market

None of us can be troubled to hand-code that if we’re in charge of the HTML of headlines regularly. I wrote my own PHP to split headlines by word and manually insert the non-breaking space on CSS-Tricks a decade or more ago. It can be done in client-side JavaScript too, naturally, but nobody wants to see that reflow.

Finally, along comes the web platform with something that looks like a solution:

h1, h2, h3 {
  text-wrap: balance;
}

Tyler Sticka has an article about this new CSS and offers this clear comparison:

uh oh — at this width, we get an orphan
yay — no more orphan (or widow or whatever, my brain cannot learn which is which) with text-wrap: balance

That “balanced” headline nice, generally a much more pleasing result for multi-line headlines.

But notably, what is happening here isn’t explicitly orphan-fighting. Richard Rutter makes this clear in an article of his own:

What this is not is control over widows and orphans. My previous examples show how the text balancing algorithm in Chrome Canary does indeed prevent a widow (the single word dropped down), and that’s a highly likely outcome. But you have to remember that the balancing job shortens the lines, so this isn’t an approach you would take to prevent widows at the end of paragraphs. In fact Canary limits balancing to 4 lines.

So it works for avoiding orphans/widows, but almost as a side effect of the balancing. In a follow-up article, Richard shines a light on what could be a future answer:

Bit by bit, the CSSWG seems to have been converging on a potential solution. In the current draft of the CSS Text Module Level 4, there is mention of Last Line Minimum Length. …

Amelia Bellamy-Royds took the Last Line Minimum Length idea and proposed a solution with a new min-last-line property. Her proposed property would specify a minimum length for the final line, and a minimum length for the penultimate line once you’d dropped a word or more down to address the short final line.

Ship it. Especially if it works on paragraphs in multi-col.


✨ Outstanding blog post alert! ✨

Future CSS: Anchor Positioning by Roman Komarov.

We only have the most rudimentary way to “connecting” the position of two elements in CSS today. Take an element that has non-static positioning, and you can absolutely position an element within that context. That’s about it. Kinda sad when you think about it — especially as it comes up relatively often. Mostly in the context of tooltips and context menus, where you want an element (of arbitrary DOM position) to be positioned right next to the element that needs the tooltip or context menu.

This positioning challenge is usually done with JavaScript (the cow paths have been laid), by way of getBoundingClientRect and doing various geometric math to make sure the element doesn’t wank off the edge of the browser or in any way become “data loss” as we like to say in CSS. More challenging that it seems. Letting CSS do it seems awfully nice.

CSS tends not to focus solutions on one exact need though, preferring instead to solve the problem conceptually with primitives that might solve lots of use cases. This is where Roman gets clever with things and makes examples like this connecting elements with pointing arrows (involving SVG):

But also some cool demos with a slightly more practical twist, like moving highlight menus:

Jhey Tompkins’ article on this, Tether elements to each other with CSS anchor positioning, covers things from first principles and is probably a better reference for the syntax. But Jhey being Jhey, there are some weird and clever demos as well, like this emoji finger form:

It’s a Pen, naturally.


There is a <meter> element in HTML, and Dana Byerly does a great job of showcasing it. It’s a natural fit for stuff like “You’ve uploaded 47 of your maximum 100 files” in a visually more understandable way. There is some accessibilty stuff to get right though, including using “fallback text” (the text within the element) which is used by some screen readers and will certainly be useful context. Free basic styling is nice:

Live tests as a Pen, naturally.


I like the term “CSS micro-framework” as coined here by Blake Watson.

  • May include classes for building grids, components, etc. Typically limited, though, because of the next rule.
  • Under 10kb minified and gzipped. I feel like you can’t claim “micro” or “lightweight” beyond 10kb.
  • JavaScript is optional and is not supplied by the framework.

Examples:

They aren’t just a reset and they aren’t… Bootstrap. They aren’t necessarily “classless” either, which is a whole other category of framework that only styles things based on HTML selectors.

And then, another possible ending:

As we go deeper down the path of minimal CSS starters we end up at the logical conclusion—you might not need a framework at all.

Implementing Adaptive Dark Mode Based on User’s OS Settings: A Step-by-Step Guide

Category Image 052

More and more users prefer browsing websites in dark mode to reduce eye strain and save battery life. To provide the best user experience, it’s helpful to implement an automatic dark mode on your website that adjusts according to a user’s operating system settings. In this tutorial, we’ll walk you through the steps to achieve this.

Your Web Designer Toolbox
Unlimited Downloads: 500,000+ Web Templates, Icon Sets, Themes & Design Assets


 

1. Create a CSS file for dark mode

First, create a separate CSS file called “darkmode.css” that contains the styles for your website’s dark mode. This file should include the color palette, font styles, and other design elements that cater to dark mode. For example:

body {
  background-color: #121212;
  color: #ffffff;
}

h1, h2, h3, h4, h5, h6 {
  color: #f0f0f0;
}

a {
  color: #ffffff;
  text-decoration: underline;
}

2. Link the dark mode CSS file

In your website’s main HTML file, add the following link tag inside the head section to reference the dark mode CSS file:

<link id="darkmode-stylesheet" rel="stylesheet" href="darkmode.css" media="(prefers-color-scheme: dark)" />

The “media” attribute ensures that the dark mode CSS file will only be applied if the user’s operating system is set to dark mode.

3. Detect operating system’s color scheme

Now it’s time to detect the user’s operating system color scheme with JavaScript. Create a new JavaScript file called “darkmode.js” and add the following code:

function getSystemColorScheme() {
  return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}

This function checks if the user’s operating system is set to dark mode or light mode by evaluating the ‘prefers-color-scheme’ media query.

4. Save the user’s preference

To improve the user experience, we’ll save their preference in the browser’s local storage. Add the following code to the “darkmode.js” file:

function saveUserPreference(preference) {
  localStorage.setItem('color-scheme', preference);
}

function loadUserPreference() {
  return localStorage.getItem('color-scheme');
}

These two functions save and load the user’s color scheme preference, respectively.

5. Toggle dark mode

Create a function to toggle dark mode on and off by adding or removing the “dark” class from the HTML body element:

function toggleDarkMode(enableDarkMode) {
  if (enableDarkMode) {
    document.body.classList.add('dark');
  } else {
    document.body.classList.remove('dark');
  }
}

6. Initialize dark mode based on user preference or system settings

Now, add a function to initialize dark mode on page load. This function checks if the user has a saved preference in local storage; if not, it defaults to their operating system’s settings:

function initializeDarkMode() {
  const userPreference = loadUserPreference();

  if (userPreference) {
    toggleDarkMode(userPreference === 'dark');
  } else {
    const systemColorScheme = getSystemColorScheme();
    toggleDarkMode(systemColorScheme === 'dark');
  }
}

document.addEventListener('DOMContentLoaded', initializeDarkMode);

7. Allow users to toggle dark mode manually

As a fallback and also providing a better experience for your users, it is a good practice to give them the ability to switch between dark and light modes manually. To do this, add a button or a switch element in your website’s main HTML file:

<button id="toggle-darkmode">Toggle Dark Mode</button>

Next, add an event listener for this button in your “darkmode.js” file:

function handleDarkModeToggle() {
  const currentPreference = loadUserPreference() || getSystemColorScheme();
  const newPreference = currentPreference === 'dark' ? 'light' : 'dark';

  toggleDarkMode(newPreference === 'dark');
  saveUserPreference(newPreference);
}

document.getElementById('toggle-darkmode').addEventListener('click', handleDarkModeToggle);

This function toggles dark mode, saves the new preference in local storage, and updates the user interface.

8. Listen for operating system changes

To ensure that your website’s dark mode adapts to changes in the user’s operating system settings, add an event listener to the “darkmode.js” file that listens for changes to the ‘prefers-color-scheme’ media query:

function handleSystemColorSchemeChange(event) {
  if (!loadUserPreference()) {
    toggleDarkMode(event.matches);
  }
}

window.matchMedia('(prefers-color-scheme: dark)').addListener(handleSystemColorSchemeChange);

This function checks if the user has a saved preference in local storage. If not, it toggles dark mode based on the updated operating system settings.

9. Link the JavaScript file

Finally, include the “darkmode.js” file in your main HTML file by adding the following script tag inside the head section:

<script src="darkmode.js" defer></script>

The “defer” attribute ensures that the script is executed only after the HTML document has been fully parsed.

All done! Now you have everything you need to implement dark mode on your future projects!

Mastering CSS Variables and Unlocking Their Full Potential

Category Image 052

CSS Variables, also known as Custom Properties, have revolutionized the way we manage styles and build maintainable, flexible stylesheets. They enable developers to store and reuse values throughout a stylesheet, making it easier to change themes, colors, fonts, and more with just a few updates. In this article, we’ll explore the best practices for using CSS variables, along with some helpful code examples.

Your Designer Toolbox Unlimited Downloads: 500,000+ Web Templates, Icon Sets, Themes & Design Assets

1. Defining and Using CSS Variables

To define a CSS variable, you must use the double hyphen (–) syntax. Typically, you’ll want to create your variables within the :root pseudo-class, which refers to the highest-level parent element in the DOM tree. This ensures that your variables are globally accessible.

:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --font-size: 16px;
}

body {
  font-size: var(--font-size);
}

a {
  color: var(--primary-color);
}

button {
  background-color: var(--secondary-color);
}

In the example above, we’ve defined three CSS variables: –primary-color, –secondary-color, and –font-size. To use these variables, we use the var() function, which accepts the variable name as its argument.

2. Fallback Values

One of the great features of CSS variables is their ability to provide a fallback value. This is helpful when a variable may not be defined or supported by a particular browser. To provide a fallback value, include a second argument within the var() function.

body {
  font-size: var(--font-size, 16px);
}

In this example, if the –font-size variable isn’t defined, the browser will use the fallback value of 16px.

3. Leveraging Variables in Media Queries and Theming

CSS variables are incredibly useful when combined with media queries and theming. You can quickly and easily update your styles for different devices or themes by redefining the variable values.

:root {
  --font-size: 16px;
}

@media screen and (min-width: 768px) {
  :root {
    --font-size: 18px;
  }
}

body {
  font-size: var(--font-size);
}

In this example, we’ve updated the –font-size variable within a media query. When the screen width is at least 768px, the font size will automatically adjust to 18px.

4. Working with Calculated Values

CSS variables can be combined with the calc() function to create dynamic and flexible values.

:root {
  --base-padding: 10px;
}

.container {
  padding: calc(var(--base-padding) * 2);
}

In the example above, we’ve defined a base padding value and used it in combination with the calc() function to double the padding for the .container element.

5. Handling Colors with HSL and CSS Variables

When working with colors, using the HSL color format in combination with CSS variables makes it easier to create color schemes and adjust hues, saturation, and lightness.

:root {
  --primary-hue: 210;
  --primary-color: hsl(var(--primary-hue), 50%, 50%);
  --primary-color-light: hsl(var(--primary-hue), 50%, 75%);
  --primary-color-dark: hsl(var(--primary-hue), 50%, 25%);
}

a {
  color: var(--primary-color);
}

a:hover {
  color: var(--primary-color-light);
}

a:active {
  color: var(--primary-color-dark);
}

In this example, we’ve used the HSL color format and CSS variables to create a primary color and its lighter and darker variations. By adjusting the –primary-hue value, you can change the color scheme throughout your stylesheet with ease.

6. JavaScript Interoperability

CSS variables can be accessed and manipulated using JavaScript, providing an additional layer of flexibility and dynamism. For instance, you can create user-customizable themes by modifying variables through JavaScript.

<button onclick="changeTheme()">Change Theme</button>

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%20%20function%20changeTheme()%20%7B%0A%20%20%20%20let%20root%20%3D%20document.documentElement%3B%0A%20%20%20%20let%20currentHue%20%3D%20parseInt(root.style.getPropertyValue('--primary-hue'))%3B%0A%20%20%20%20let%20newHue%20%3D%20(currentHue%20%2B%2030)%20%25%20360%3B%0A%20%20%20%20root.style.setProperty('--primary-hue'%2C%20newHue)%3B%0A%20%20%7D%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />

In the example above, clicking the “Change Theme” button will change the –primary-hue variable, effectively updating the primary color and its variations.

Wrapping Up

Variables have transformed the way we approach theming, responsiveness, and maintainability in our stylesheets. By following best practices such as global variable declaration, using fallback values, leveraging variables in media queries, working with calculated values, handling colors with HSL, and harnessing JavaScript interoperability, you’ll unlock their full potential.

With this newfound understanding, you can create more efficient, flexible, and dynamic stylesheets that adapt to different devices, user preferences, and themes with minimal effort.

Chris’ Corner: A Little Back and Forth

Category Image 052

I feel like y’all out there are like: ya know what I could use this week? A scattered collection of interesting links with light commentary about what is interesting about them or how they connect with the modern web zeitgeist. No worries gang, I got ya.


I like Josh’s take on all this coding + AI stuff and the fear of lost jobs. It’s terrible timing for all this because fricking tons of people are losing tech jobs in layoffs right now. But that isn’t because AI is taking their jobs, it’s economic fears, correcting overhiring mistakes, and some greedy “ooo look we can do mass layoffs and not get much flack for it because everyone is doing it”. Anyway here are some quotes from Josh’s article:

… since the beginning, there’s been a concern that web developers would be made redundant by some new technology. In the 2000s, it was WordPress. In the 2010s, it was Webflow. In the early 2020s, it was “no code” tools.

[on GPT-4 building simple website from napkin drawing] … we haven’t needed web developers to build these sorts of pages in decades. There is an enormous difference between this HTML document and the sorts of code front-end developers write today.

Code snippets are all over the internet, and are often generic. By contrast, every codebase is unique. There are very few large open-source codebases. How’s the AI supposed to learn how to build big real-world projects?

I actually think that this could increase the total # of developer jobs.

Certain tasks might be delegated to an AI, but not many jobs.

Normally I skip or roll my eyes at people’s hot takes on AI stuff since there is just so much of it right now, but again I think Josh’s takes here are smart. It’s also in agreement with most other takes I’ve read on this. Generally, people are writing articles trying to address people’s fear, but the fear seems a little invented.


A little accessibility back and forth!

I suppose the powers that be should listen to web accessibility experts over me, but I’m more inclined to agree with Ben here. The cowpaths are there, pave them.


Another back-and-forth took place last month between Alex Russell’s The Market for Lemons and Laurie Voss’ The case for frameworks. As much as I prefer to rate these arguments on the written word entirely, the fact is I know that both of these people are Very Big Web Personalities that both very much like to argue. Laurie for the most part brings baby-bear porridge to the party and I like that, but I also don’t mind Alex bringing down the hammer and taking hard-line stances on web performance, mostly because not a ton of other people do that and the web could use the pushback.


A good amount of web platform arguments end up being about JavaScript frameworks and the whole idea of SPAs. Probably no question we overdid it as an industry on the SPA thing. One side plot here though is that this was all happening during a time when the web was perhaps a bit more threatened by “native” apps than it is now. Native apps have a certain feel to them that is a bit different than web apps generally, and no small part of that is how they tend to animate their state and page transitions moreso than web apps do. SPAs made that far more possible than we were able to do on standard new-page-loading web apps.

Transitioning interfaces and page transitions in non-SPAs isn’t just sitting around waiting to be solved though. I think of three things:

  1. Swup is a JavaScript library just for this stuff which is being actively developed. There is also Taxi.
  2. Turbo looks still actively developed too, and while it’s not about transitions specifically, it’s about making a non-SPA behave like an SPA meaning you don’t need to change architectures but can still benefit from a page that never 100% reloads.
  3. The biggest deal is still the View Transitions API which has just landed now in stable Chrome. No libraries needed. No SPA needed. Just straight-up animations between state and page changes in native JavaScript.

I mentioned the other week that Firefox fixed this old bug a bit related to drop caps, but really, or I guess in addition to that, the best thing that can happen to drop caps is the CSS initial-letter property. I should have linked up Stephanie Stimac’s article Greater styling control over type with `initial-letter` which digs into that and strongly makes the case.

Ethan Marcotte has a wonderful video showing how to do drop caps well, but it’s frustratingly complicated. Really looks like initial-letter is the answer to all this.

Mastering CSS Border Style: A Comprehensive Guide

Category Image 035

CSS Borders refers to the line outside the padding and inside the margin of the CSS Box Model. This line wraps around the padding and content in every HTML Element. That is both semantic and non-semantic elements.

Borderlines don’t have to be a solid straight line. We can apply different styles to it to change its looks and feel, as you will see as we learn more about it in this blog on CSS Borders.

Chris’ Corner: Fresh SVG Drop

Category Image 052

Lemme show off some cool SVG-related things this week. Gotta love SVG. It’s this graphics language built right into the web platform that has a ton of capability and is always right there waiting for us when we need it. Thanks the web!


Portability is a cool SVG feature. You can copy and paste a bit of SVG right into HTML and that’s not only functional but actually, a pretty good way to do it. That way you can style it freely and no additional network request is made.

Ya know… that’s how our icons feature works here on CodePen.

The Assets panel on CodePen offers one-click SVG icons from Font Awesome.

And it’s a decently common way to deliver UX on a set of SVG icons generally. For example, check out Monika Michalczyk’s Shapes project, where you can just click any of them and get all the code right on your clipboard. They paste into Pens really nicely, of course.

I like how weird they all are. Nothing practical in here, just lovely interesting shapes. I bet they would morph into each other in fun ways.

Or here’s Robb Knight’s Mac 30th Anniversary Icons which are super cool minimalist representations of Macs over the last many decades.

No click-to-copy here, but the downloaded versions you can drag-and-drop into the CodePen editor if you want to play with them there.

You can learn the SVG syntax. I guess that’s kinda obvious but maybe not to everybody as SVG is often the output of tools. You can export SVG from Figma and Illustrator and stuff and you didn’t have to learn the syntax, you just use the output.

Just SVG paths alone are fairly complicated and something of a sub-syntax. I wouldn’t say I know it super duper well, but I know enough that I wrote a guide a while back.

Some of the other attributes of SVG elements are a bit more straightforward like circle essentially has a central point at an X, Y coordinate and then a radius. Sébastien Noël has a new guide on fffuel that helps understand a lot of these syntaxes:

I just love interactive code examples like this.

But leave it to yuanchuan (creator of css-doodle) to Experimenting [with] A New Syntax To Write SVG. It’s centered around the idea that the stylistic SVG attributes can be moved to a CSS-like syntax, which doesn’t just select and style SVG, but creates it.

Check out how easy it is to play with on CodePen.

OK I saved the best for last for you: Draw SVG rope using JavaScript (and it’s not just because there is an excellent CodePen demo) from Stanko Tadić. And not just rope like a line that maybe has some basic physics, but real-looking twisted rope, like the kind that might be holding a large ship to dock. The journey, which is excellently documented, involves really digging into the SVG APIs, doing interesting math, and knowing about fancy algorithms and stuff (see “Chaikin’s method” for rounding). I like it when you can tell someone is clearly captivated by an idea, gets it all figured out, then documents it so well the output and the explanation are equally interesting.

Chris’ Corner: Websites, Highlights, and Guesses

Category Image 052

I love Henry’s guide: How to Make a Website.

There is precious little recent instructional material on how you can build a website, a perfectly great website, using just the raw materials of the web. Raw HTML & CSS, as it were. But that’s not all that Henry’s guide is about. It’s full of holistic advice going well beyond web design:

Be kind and curious and humble when you’re working with folks, and be extra forgiving of their mistakes, so when the time inevitably comes that you make your own, there’s perhaps some goodwill in the vault for you.

 🙏

I do suspect if it’s not just lack of awareness that you can build a website with just hand-written raw HTML and CSS, but more of a then what? situation. Of course, we’re hoping CodePen is a place where that is a good option and are working to make that better every day. But there are plenty of options for getting that locally crafted HTML website to a real website, like Vercel, Netlify, GitHub pages, etc, which all make it pretty decently easy. It would be unfortunate if the DevOps knowledge for getting websites to production is just as much knowledge as actually making websites.

Oh hey this makes me think of a great term thrown out by Robb Owen: Hand-thrown frontends. He compares the website-making process to the ceramics process of making a bowl out of clay.

So, for me, the frontend bowl-making process is a cyclical, non-linear one. On a surface-level it probably doesn’t seem like it’s as efficient as assembling Lego bricks to order, but over time you’ll make more bowls and each phase of iteration will gradually shorten as your skill increases towards mastery.

I’m a sucker for a good ceramics analogy as that’s what my Bachelor of Arts was focused on in college.

Oh! And speaking of Ceramics, have you seen Charlotte Dann’s Ceramics project? It’s probably my favorite generative art project I’ve ever seen. This surface is totally code-generated:

Might as well be a photograph of real carved, glazed clay.

Oooooo tricky CSS challenge! Skewed Highlights. Vadim Makeev did up good:

You’d think transform: skew() would be involved somehow, but there isn’t a great opportunity for that, especially with arbitrary line breaks and such. Instead, the backgrounds are created with multiple gradient backgrounds (super clever) and fortunately box-decoration-break: clone; makes it look reasonable across lines.


Musing about slight alterations in CSS selector structure and how it affects selections? Sign me up for that party! Bramus compares:

.a .b .c { }
/* Versus! */
.a :is(.b .c) { }

They do look and behave similarly, but the former enforces that “c is a child of b is a child of a” situation solidly, while the latter allows for a situation where c is a child of a which is a child of b. That’s way too hard to understand in words, so here’s an image:

Admittedly I don’t reach for :is() all that much, but I suspect usage might go up a bit now that native CSS nesting is here and that all nested selectors must start with a symbol. So a quick way around wanting to nest element selector is wanking it in an :is():

header {
  h1 { } /* nope */
}

header {
  :is(h1) { } /* yup */
}

Let’s end with a little collection of developers looking forward to upcoming tech trends. This is, of course, popular in January and it’s March now but gimme a break I’m a little slow sometimes.