We might leave a text input unstyled. We might leave a link unstyled. Even a button. But checkboxes… we don’t leave them alone. That’s why styling checkboxes never gets old.
Although designing checkboxes is not that complicated, we also don’t have to settle for simple background color changes, or adding and removing borders, to indicate state changes. We also don’t have to pull out any fancy design skills — that we don’t possess — to make this work. I’ll show you how.
Basics
In the following demos, the checkboxes pretty much have the same three-stack layout — at the bottom is a checkbox, and on top of it are two stacked elements, or pseudo-elements. The checkbox is indicated as checked or unchecked depending on which of the two is visible.
If you look at the CSS code in the pens you’ll notice all the layouts — including the one for the checkboxes — are grids. You can use other layouts that feel right for your use case (and learn more in the CSS-Tricks Grid Guide). Additional notes on code and design alternatives are at the end of the source code inside the pens.
In addition, any elements stacked on top of the checkbox have pointer-events: none so they don’t prevent users from clicking or tapping the checkbox.
Let’s now get to the first method.
Idea 1: Blended backgrounds as a state
Blending in CSS is a versatile technique. Manipulating colors relative to two or more elements or backgrounds can be handy in contexts you might not have thought of.
One such instance is the checkbox.
CodePen Embed Fallback
<input id="un" type="checkbox"> <label for="un">un</label>
<!-- more checkboxes -->
In this demo, I’ve styled the checkbox’s pseudo-elements green and blue, stacked them up, and gave them each a mix-blend-mode value. This means the background of each element blends with its backdrop.
I used the hard-light value, which emulates the result of either multiply or screen depending on if the top color is darker or lighter. You can learn in depth about different blend modes over at MDN.
When the box is checked, the ::after pseudo-element’s mix blend mode value is unset, resulting in a different visual.
Idea 2: Make a 3D animation
Animating a block of color is fun. Make them seem 3D and it’s even better. CSS has the means to render elements along an emulated 3D space. So using that, we make a 3D box and rotate it to indicate the checkbox state change.
.c-checkbox > div {
transition: transform .6s cubic-bezier(.8, .5, .2, 1.4);
transform-style: preserve-3d;
pointer-events: none;
/* more style */
}
/* front face */
.c-checkbox > div > i:first-child {
background: #ddd;
transform: translateZ( -10px );
}
/* back face */
.c-checkbox > div > i:last-child {
background: blue;
transform: translateZ( 10px );
}
/* side faces */
.c-checkbox > div > i:nth-of-type(2),
.c-checkbox > div > i:nth-of-type(3) {
transform: rotateX(90deg)rotateY(90deg);
position: relative;
height: 20px;
top: 10px;
}
.c-checkbox > div > i:nth-of-type(2) {
background: navy;
right: 20px;
}
.c-checkbox > div > i:nth-of-type(3) {
background: darkslategray;
left: 20px;
}
The <div> after the checkbox becomes a container of a 3D space — its child elements can be placed along the x, y and z axes — after it’s given transform-style: preserve-3d;.
Using the transform property, we place two <i> elements (grey and blue colored) with some distance between them across the z-axis. Two more are wedged between them, covering their left and right sides. It’s like a cardboard box that’s covered except at the top and bottom.
When the checkbox is checked, this grey and blue box is rotated sideways to face the other side. Since I’ve already added a transition to the <div>, its rotation is animated.
input:checked + div {
transform: rotateY( 180deg );
}
Idea 3: Playing with border radius
Changing a checked box’s border radius? Not that fun. Changing also the border radius of other boxes near it? Now we have something.
CodePen Embed Fallback
<input type="checkbox" id="un"> <label for="un">un</label>
<!-- more rows of checkboxes -->
If you’d just interacted with the demo before, you’ll notice that when you click or tap a checkbox, it not only can change its own borders but also the borders of the boxes after and before it.
Now, we don’t have selectors that can select elements prior, only the ones after. So what we did to control the appearance of a preceding box is use the pseudo-element of a checkbox to style the box before it. With exception of the first box, every other box gets a pseudo-element that’s moved to the top of the box before it.
Let’s say boxes A, B and C are one after another. If I click B, I can change the appearance of A by styling B’s pseudo-element, B by styling C’s pseudo-element, and C by styling D’s pseudo-element.
From B, the pseudo-elements of B, C and D are accessible — as long as the next element selector can be used between them in the layout.
The four corners of each checkbox are initially rounded when checked and unchecked. But if a box is checked, the following box’s top corners and preceding box’s bottom corners are straightened (by overriding and removing their border radii).
Idea 4: Using a CSS mask
Toggles, switches… they are also checkboxes as far as the code goes. So we can style the boxes as toggles for this one, and it’s done with a CSS mask, which Chris has written about before. But in a nutshell, it’s a technique where we use an image to filter out portions of its backdrop.
.one.skin {
background: no-repeat center -40px url('photo-1584107662774-8d575e8f3550?w=350&q=100');
}
.two.skin {
background: no-repeat center -110px url('photo-1531430550463-9658d67c492d?w=350&q=100');
--mask: radial-gradient(circle at 45px 45px , rgba(0,0,0,0) 40px, rgba(0,0,0,1) 40px);
mask-image: var(--mask); -webkit-mask-image: var(--mask);
}
Two skins (displaying landscape photos) are on top of a checkbox. The topmost one gets a mask-image that’s in the shape of a typical toggle switch — a transparent circle at the left, and the rest is a fully opaque color. Through the transparent circle we see the photo below while the rest of the mask image shows the photo at the top.
When a checkbox is clicked, the transparent circle is moved to the right, so we see the image at the top through the circle while the rest shows the photo at the bottom.
There are some CSS properties that can be animated by default and one of them is box-shadow. This type of subtle animation goes well with a minimalist theme.
That’s it! I hope this sparks some inspiration the next time you find yourself working with checkboxes. CSS gives us so many possibilities to indicate state changes, so have a little fun and please share if you have any interesting ideas.
Browse through Dribbble or Behance, and you’ll find designers using a simple technique to add texture to an image: noise. Adding noise makes otherwise solid colors or smooth gradients, such as shadows, more realistic. But despite designers’ affinity for texture, noise is rarely used in web design.
In this article, we’ll generate colorful noise to add texture to a gradient with only a small amount of CSS and SVG. Alright, let’s make some noise!
Check it out here. The quickest way to understand what’s happening is to play with the parameters that make up the layers.
The trick: SVG noise and CSS gradients
The core technique in this article is built on top of a Stack Overflow answer by Chris Pachl to the question: Can you add noise to a CSS gradient?
The trick is to use an SVG filter to create the noise, then apply that noise as a background. Layer it underneath a gradient, boost the brightness and contrast, and that’s it — you have gradient that gradually dithers away.
The key ingredients
Here’s what we’re working with under the hood:
SVG turbulence: This is our noise filter.
Background with gradient and SVG: Next, we drop that filter into CSS as a background image that combines the filter with a CSS gradient.
Boost brightness and contrast: Then we turn to CSS filter to increase the brightness and contrast of the noise.
Blend gradients: Finally, we optionally use mix-blend-mode to further filter out colors and blend gradients together.
Let’s go into detail on each of these parts.
Using SVG turbulence
Within the realm of SVG, we can define filters, and one such filter lets us create Perlin noise. It’s called <feTurbulence> and we can define attributes, such as whether it is “turbulence” or “noise” and how fine or coarse it is. Bence Szabó explains it in much more detail as he demonstrates how it can be used to create patterns.
This SVG example creates a filter and renders a <rect> element that we can use for our grainy gradients. Notice that the SVG <filter> is defined separately from the <rect>, and the <rect> simply references it.
Play around with changing some of the properties of <feTurbulence>
CodePen Embed Fallback
We’re going to save this SVG as a separate file. We reference an external link to grab the SVG in the demos throughout in this article. In practice, though, you would reference a local file or your own CDN. It doesn’t work to reference the SVG by its id in CSS, for some quirky reason, but you can inline the SVG, as we show in the playground demo. We don’t do this in the demos for legibility reasons.
Creating a CSS background with SVG and a gradient
After we have the SVG file stored somewhere we can reference it by a URL or path, we can now use it in a CSS background, combined with a gradient.
Order matters here. In this particular example, we want a solid color (i.e. no noise) to transition into noise and then into another color. We also want one end of the gradient to be transparent so that the noise shows through.
Like this:
CodePen Embed Fallback
However, this isn’t particularly nice because the noise is too muddled. We need to fray it and make it grainier. We can do that by…
Boosting the brightness and contrast
Adding a CSS filter makes the noise more stark, pushing the most faded colors towards white or black. The filter applies to the entire <div>, so the leftmost blue is a different blue than the pure blue we started with.
You can play around with how contrast and brightness affect the gradient. Boosting the brightness and contrast pushes out the muddled grays in the follow demo.
CodePen Embed Fallback
The noise is not uniform in color
If you zoom in, you’ll notice that the noise is made up of many colors. The SVG filter was colorful to begin with, and increasing the brightness and contrast emphasized certain colors. Although hardly noticeable, if this confetti is unwelcome, we can continue to filter out colors with CSS blending (i.e. mix-blend-mode and background-blend-mode ).
CSS blending
Let’s make a grainy gradient that transitions between two colors. CSS blending allows us to stack layers of color. In the next example, we’re adding another <div> to the markup, positioning it over the original gradient, then applying mix-blend-mode: multiply; to smooth things out.
We can use the CSS isolation property to create a new stacking context and choose what gets blended. If we were to leave out isolation in the next example, the gradient and overlay would blend with the background color. Try it in the Pen and comment out that line!
/* Same as before */
.isolate {
isolation: isolate;
/* ... */
}
CodePen Embed Fallback
Some use cases
We’ve looked at a pretty simple example of how to make a noisy gradient, but where might you use one? Let’s consider several use cases.
Light and shadows, with grain
Where do gradients naturally occur? Light and shadows, for one. We can take advantage of the CSS property mix-blend-mode to smoothly blend gradients and selectively filter the colors we want to see in the noise.
CodePen Embed Fallback
In the “shadow” example, we create a dark gradient, and invert it to create the effect in the “light” example. In both cases, mix-blend-mode allows us to blend it with other gradients.
CodePen Embed Fallback
Holographic foil
The drastic brightness and contrast boost creates a rainbow effect that’s reminiscent of holographic foil.
CodePen Embed Fallback
Taking things further
Try the playground and mess around with the different parameters to see how they affect the texture.
Beyond that, here are some ways to continue fiddling with this technique:
Use a different SVG: All of the gradients in this article use the same SVG, but you can toy with the parameters that generates the noise to adjust the coarseness as well as the look and feel in the playground.
Try different gradients: Besides linear-gradient, CSS offers four more types of gradients. Can you name them? (Here’s one.)
Add more layers: With CSS blending, you can stack as many any layers as you’d like and blend them down.
Apply different SVG filters: There are all kinds of filters, including Gaussian blur and different types of lighting. Plus, they can be referenced in a CSS filter and applied to any element in addition to SVG.
What else can you think of? Please let us know what you discover in the comments.
Browser support
We can’t escape talking about browser support here. The core of this technique is supported by all modern browsers. As you might expect, it does not work in Internet Explorer. That said, Internet Explorer does support SVG as a background in CSS (just not with the actual CSS filter property).
SVG as a CSS background image
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome
Firefox
IE
Edge
Safari
5
24
9
16
5
Mobile / Tablet
Android Chrome
Android Firefox
Android
iOS Safari
93
92
3
4.2-4.3
CSS filter effects
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome
Firefox
IE
Edge
Safari
18*
35
No
79
6*
Mobile / Tablet
Android Chrome
Android Firefox
Android
iOS Safari
93
92
4.4*
6.0-6.1*
I’ve also noticed that Blink-based browsers (e.g. Safari) and WebKit-based one (e.g. Chrome) implement mix-blend-mode slightly differently, so please be sure to test across browsers if using CSS blending. In my own projects, I’ve used browser-specific media queries to manually reconcile the visual differences with small tweaks to CSS.
That’s it! Now that you have a grasp of SVG filters and how to combine them with CSS filters as a background, you have yet another neat visual effect to add depth and texture to a design.
I feel like my quest to make sure this site had pretty sweet (and automatically-generated) social media images (e.g. Open Graph) came to a close once I found Social Image Generator.
The trajectory there was that I ended up talking about it far too much on ShopTalk, to the point it became a common topic in our Discord (join via Patreon), Andy Bell pointed me at Daniel Post’s Social Image Generator and I immediately bought and installed it. I heard from Daniel over Twitter, and we ended up having long conversations about the plugin and my desires for it. Ultimately, Daniel helped me code up some custom designs and write logic to create different social media image designs depending on the information it had (for example, if we provide quote text, it uses a special design for that).
As you likely know, Automattic has been an awesome and long time sponsor for this site, and we often promote Jetpack as a part of that (as I’m a heavy user of it, it’s easy to talk about). One of Jetpack’s many features is helping out with social media. (I did a video on how we do it.) So, it occurred to me… maybe this would be a sweet feature for Jetpack. I mentioned it to the Automattic team and they were into the idea of talking to Daniel. I introduced them back in May, and now it’s September and… Jetpack Acquires WordPress Plugin Social Image Generator
“When I initially saw Social Image Generator, the functionality looked like a ideal fit with our existing social media tools,’ said James Grierson, General Manager of Jetpack. ‘I look forward to the future functionality and user experience improvements that will come out of this acquisition. The goal of our social product is to help content creators expand their audience through increased distribution and engagement. Social Image Generator will be a key component of helping us deliver this to our customers.”
Daniel will also be joining Jetpack to continue developing Social Image Generator and integrating it with Jetpack’s social media features.
Rob Pugh
Heck yeah, congrats Daniel. My dream for this thing is that, eventually, we could start building social media images via regular WordPress PHP templates. The trick is that you need something to screenshot them, like Puppeteer or Playwright. An average WordPress install doesn’t have that available, but because Jetpack is fundamentally a service that leverages the great WordPress cloud to do above-and-beyond things, this is in the realm of possibility.
Automattic is always on the prowl for companies that are doing something interesting in the WordPress ecosystem. The Social Image Generator plugin expertly captured a new niche with an interface that feels like a natural part of WordPress and impressed our chief plugin critic, Justin Tadlock, in a recent review.
“Automattic approached me and let me know they were fans of my plugin,” Post said. “And then we started talking to see what it would be like to work together. We were actually introduced by Chris Coyier from CSS-Tricks, who uses both our products.”
Sarah Gooding
Just had to double-toot my own horn there, you understand.
The name zero-width space is antithetical, but it’s not without uses. In text, maybe you’d use it around slashes because you want to be sure the words are treated individually but not have any physical space around the slash:
That’s an image. WordPress was being weird about it and not escaping it even when in a code block.
That’s pretty theoretical though—I’ve never once needed to do that. It might be useful in a long word to suggest that it can be broken there… but that’s also rare as we have the soft-hyphen (­) which is designed for that and leaves a typically appropriate hyphen at the break.
What I have needed to do is exactly the opposite: trick a system into thinking a single word is two words. Like on Twitter, if I @username or #hashtag in the text of a tweet, those will be linked up respectively. But I don’t always want that. On CSS Twitter, I might want to refer to a @media query or show an #id-selector. Toss a zero-width space between the symbols and the text and I’m all set.
Get a zero-width space on your clipboard
Here’s a Pen I created ages ago that will help you do that:
CodePen Embed Fallback
There is also a quick trick for doing it from the browser console:
copy('u{200B}')
via:
Twitter tip: To prevent usernames and URLs from being converted to links, interrupt them with a zero-width space.
And for yet another way that may appeal to you, a bookmarklet!
CodePen Embed Fallback
Copy & Paste concern
The danger with the zero-width space is, well, you can’t see it. If someone were to, for example, copy your @media query using the zero-width space trick from a tweet, it won’t work in their code editor (because it will invalidate the rule) and it might be extremely confusing. For that reason, it’s probably good to avoid using it in anything that might be copied as a code example, but probably fine when explicitly trying to not autolink something.
Like it or not, meetings are essential to a good working environment and communication. Therefore, it’s crucial that we work on making them as productive as possible. Today we’ll explore myriad ways to keep meetings coordinated, well documented, and talk about how to recognize and steer away from anti-patterns.
I’m timid to write this because I have not always hosted good meetings. I have, however, hosted thousands of them, so I’ve learned both from some mistakes and successes. In all likelihood, if you do any kind of management or lead work for a while, you’ll also see your own spectrum of meetings: meetings with different types of agendas and purposes, meetings with varying levels of awkwardness, meetings that didn’t have a formal outcome. We’ll dive into all of these in this article, as well as some tips for each.
The truth is, a meeting by its nature can almost never be perfect because it is by definition a group of people. That group of people will consist of different people: with different tastes, different opinions, different priorities, and different values. There’s a high chance that not everyone will agree on what a great meeting is. So half of the journey is aligning on that.
The Good, The Bad
One thing’s for sure: we can agree on what a bad meeting is. So let’s start by using that as a ballast:
There’s no clear purpose or direction
It feels chaotic
The wrong people are there
People are generally disrespectful of one another
Everyone feels it’s a waste of time
From those assertions, we can then derive what a good meeting is:
The purpose of the meeting is clear
There’s an agenda (we’ll dive in to the complexity of this in a moment)
There are the right people in the room. Not too many where communication is overly complicated, not too few where the people you need to move forward aren’t there.
There’s some order. People aren’t dropping in and out, talking over each other, or being generally inconsiderate
There’s a clear decision, outcome, and next steps at the end
Purpose of the Meeting and Direction
The first point and the last are connected: to have a good meeting, there is a core. You’ve all come for a unique purpose, and the end of the meeting should encapsulate what you’ve learned about that purpose and what the next steps are. Thus, the beginning and end of the meeting might sound a little similar:
We’re all here today to discuss how we’re going to support the next version of framework X. I have some new data to show you that frames the direction, Hassan and Jenna are here to talk about some of the details of the implementation, and Angela, we’d love to coordinate with you on a rollout process because it affects your team.
And at the end:
OK, so we decided we’re going in Y direction. Angela, your team seems comfortable doing Z, is that correct? And the rollout timeline we’ve agreed on is 5 weeks. The next steps are to explore the impacts of A, B, and C and reconvene in a week on our findings and process.
This is just an example—it’s not important to model this precisely. But you should be aligning at the beginning and end of the meeting to make sure that nothing major is missing and everyone is on the same page. If you haven’t come to a decision by the end of the meeting, then your next steps may be either to figure out who will make the decision and inform everyone or roll over to a new meeting.
Ideally these sentences are encapsulating information everyone needs:
The shared purpose
What you’re doing about getting to that outcome
Who is owning what
How
When, what are the timelines
If there are people there who do not need to know this information, they probably shouldn’t have been at the meeting in the first place.
The Agenda
Beyond deciding that a meeting should have an agenda, there are so many ways and means an agenda can be used. Strangely enough, an agenda can also be a way to not have a good meeting, so let’s explore that, too.
An agenda should ideally always state the purpose of the meeting. I personally love to then include some bullets as talking points, as well as space to take notes right in the document during the meeting.
Sometimes people use an agenda to write thoughts down before the meeting, and I would strongly suggest you steer clear of this—there’s nothing wrong with a person keeping notes for themselves for the meeting but if you come to a meeting where an agenda is locked top to bottom with material, it can sometimes shut down the collaborative aspect of the meeting—which means it shouldn’t be a meeting at all, it should just be a shared doc, to be consumed async. Part of the purpose of the meeting is the discussion itself. Again, louder:
Part of the purpose of the meeting is the discussion itself.
Not all meetings are the same
There are also different kinds of meetings. Let’s go over what type of agenda you might use for each:
Brainstorming session: perhaps you don’t want a full agenda, just the purpose and a notes section, or even a Miro board or other whiteboarding tool to use for capturing people’s thoughts, with small areas stubbed out.
Weekly discussion or daily standup: I typically have folks add whatever they like to ours, prefacing their contribution with their name and a small category, for instance, RD for rapid decision, D for discussion, and P for process. Here’s an example:
- [Sarah, RD] should we block off 4 hours to triage our iceboxed issues?
Our team uses a kanban board during the standup and people take turns talking about what they’re doing for that time period. It’s nice how it helps solidify the tasks and priorities for the week, and allows for some course correction if there’s accidental misalignment before the work is done.
We also talk about what was done or shipped in the previous week so we can celebrate a little. Especially on tasks we know took the person a long time or took a lot of effort.
We found through trial and error that twice a week check-ins suited us: once on Monday to kick the week off, and again on Wednesday to keep us aligned and the momentum going.
Cross-Functional meetings: This is one where a more formal agenda with some preparation can be really helpful, so that all parties have enough information about the purpose and what’s being discussed. If you have a lot of information, though, I would suggest creating a one-sheeter and sharing that ahead of time instead of adding everything to an agenda. Sometimes if I know everyone is too busy to read everything async, I will give the first 5 minutes to the group to read through the one-sheeter on the call so we’re all on the same page. People usually appreciate this. YMMV.
All this said, agendas are very useful, but I’ve seen strange culture arise from making strict rules around them. The point of the agenda and meeting is to collaborate on something. That point is nullified if folks are putting process ahead of that impetus.
The best cultures I’ve worked at use both meetings and agendas as tools for working together effectively- tools that everyone equally feels responsible for making useful.
All Kinds of Awkward
OK, you led a meeting! You gave people purpose, you set direction and timelines. But why was it so awkward?!
Not all forms of awkward are bad, really. There are different kinds of awkward, and some are quite natural, some are more harmful. Let’s analyze this for a moment, starting from most innocuous to something more insidious.
You all didn’t know each other well
The team I got to work with at Netlify was some of the silliest, most collaborative, and trustworthy groups I’ve ever had the pleasure of working with. We actively cultivated this culture and it was great fun. Every meeting started with goofing off and chatter. Then, when we got to business.
The meeting would flow effortlessly because we were all comfortable together. One time a friend in the People department asked “what do you do to break the ice with your team”, and I jokingly responded “ice? Our team? No… we don’t need that… maybe we should be frozen?”
Not all conversations are going to be like this. We knew each other fairly well and actively worked to have vulnerability together. If your meetings with other groups you don’t know well have awkward moments, that’s actually pretty natural, and nothing to be too concerned with. You can try to make conversation and that can help, but trying to force it too much can also feel a bit stilted, so just ease up on the guilt for this one. There’s nothing wrong with you, I promise.
There were too many people
During the pandemic, my husband and I would sometimes try to replace in-person dinner parties with zoom versions of the same. What we learned was they didn’t quite work at scale. When you have an in-person party with 12 or more people, everyone doesn’t really stay in one huddle together, they break off to smaller conversations. When we started hosting the zoom parties with smaller groups, the calls became more fluid, relaxed and comfortable.
There’s a certain scale at which conversation begins to feel performative because there are so many eyes on a person when they’re speaking. Meetings are very much the same. Try not to invite too many people to a meeting. If you are worried folks might not feel included unless you invite them, you can either mark them as optional or let them know you’ll be sure to tell them the outcome.
If you’re inviting too many people because there’s a company culture that everyone should be involved in every decision, that might be a sign of a wider issue that needs some solving. Companies at a certain scale start to have issues functioning if there is no clear understanding of ownership. If you’re inviting everyone out of fear of hurt feelings often, it’s likely not a problem with your meetings, and more a sign that you need some clarity. See the DRI section at the end of this chapter for more information on how to mitigate this.
There’s something people aren’t saying
This kind of awkward is probably the most harmful. If the meeting is awkward because people don’t feel comfortable telling the truth, or there’s an elephant in the room, or there’s a smell that needs to be dealt with. Elephant smells? Ok, moving on.
We should watch out for this and try to do something about it. Personally, I’m a “walk towards the fire to put it out” kind of person, and will actually just acknowledge that it’s awkward because it doesn’t feel like we’re being transparent with one another. I’ll state what I know from my perspective and then ask if other folks are feeling the same.
If you do this, you’ll usually have to wait a beat or two. People will likely be a bit shocked that you came right out and said it. It will take them a couple of seconds to adjust and consider what will happen if they tell the truth, too. It’s crucial that you not speak to fill the silence in these moments. It will feel very uncomfortable, but I promise, you have to let the silence hang for a bit before someone speaks up. Typically from there, people will all start speaking, and you can actually dig into the problems.
Conflicts
There’s an entire chapter devoted to conflicts because the topic is big and nuanced enough to warrant its own time and space, but let’s apply some of the principles here, because there is an intersection of good meetings and dealing with conflicts directly.
The most important piece here is that conflicts are not something to be avoided. It’s not bad that people feel passionate about their work, it’s great. Not all conflicts are negative- the point of the meeting may be to bring to light where folks aren’t aligned. There probably is some base premise or problem they are all trying to solve, but they see the solution differently. It can help to find the alignment there so the ideas can be fleshed out without being attached to a particular person’s identity.
The identity thing can be a pitfall, because if you have two people discussing their idea instead of an idea, it can feel to them like someone is rejecting them rather than a concept.
We want to try to guide towards an approach where it doesn’t feel like anyone is attacking one another, and also manage actively against people being disrespectful to one another. It’s the job of a manager to disambiguate healthy conflict from attack so that respectful discourse is encouraged. If folks are putting out ad hominem attacks, it’s on you to reel that in and move the conversation towards the work instead. Otherwise, it really is hard for the conversation to stay productive.
Typically I’d say it’s good to hear people out, and then reign things back in by discussing what you think you’re hearing and tying it back to a shared purpose. Then we find where we have common ground. Here’s an example:
“What I’m hearing is that Rashida feels that team X is migrating a system that affects her team while they are trying to release a big feature. Is that correct? And that Jerome feels that it’s crucial that team X be able to migrate the system soon for stability purposes. Is that correct?
“OK, well, it sounds like we have a shared goal of making sure the company can ship features with some stability. Perhaps we can talk through what timelines are immovable and which are not so that we can stay coordinated?
“I’m sure we all want to be able to ship said feature without any hiccups and also get the new system up and going”
Here, we stated what we thought we were hearing, which allows for the person to either feel heard or correct us if we’re mistaken and there’s a miscommunication. (Sometimes there is!)
Then we stated the shared goal from both parties, as well as risks and constraints that may play a part in some of the conflicts that need to be ironed out.
You’ll note in the last sentence, we try to tie a knot for a vision of stability that addresses both of their understandable needs.
A couple of things to note: I’m giving an example here and you absolutely don’t have to do it like me. The most important thing is that folks feel heard and that you all agree on what the conflict is. And that you remain open to that discussion, while finding the base premise of why you’re even talking about it.
It’s also way easier said than done. If you have a conversation that goes off the rails, I’d suggest spending a bit of time after you’re off the call to write down what you think happened.
I tend to give myself a section to just talk through the facts of what happened, and then another to talk through my feelings of what went poorly and what could have been better. It helps to check in with the facts separately because our human brains can sometimes try to protect us and see a particular version of an event. Hard to do, but checking in with just the facts helps ground that a bit.
There can be times where a strong conflict happens during a meeting and you’re at an impasse, and you need to give folks time to regroup. I’d suggest calling another meeting in a week as a follow up, and try to hear people out individually in the meantime. Sometimes people need a little distance from a matter, or they’re having a hard day, and that’s totally ok.
The DRI
The DRI stands for “Directly Responsible Individual” and is one of the most important pieces that we haven’t covered yet. A good meeting must have a DRI, and it is not necessarily the person who called the meeting. It might not be you. But you must designate who owns the project and ultimately makes decisions when there’s one to be made.
Why do you need a DRI? Well, as much as you do want to hear input from everyone, eventually you have to make a decision, and there are plenty of things in software development that don’t necessarily have one true answer.
Note that the phrasing is not PWMD (Person Who Makes Decisions) though that acronym looks pretty hardcore. Instead, we use Directly Responsible Individual because that’s also core to deciding who this person is. They are the person who is going to own the outcome.
That’s part of why not everyone can get equal say- if it’s your project and you are on the line for the outcome of whatever decisions are made, you can see how you would also need to own decision making. And likewise, if people who have no skin in the game decide things, they might not understand all the moving parts or invest as much in the gravity of the matter.
The appointment of the DRI not only unlocks the groups to make final decisions and move forward, but also places the responsibility on the party that will carry the weight.
There are several systems of ownership you can explore, such as DACI, which separates out Driver, Approver, Contributors, and Informed so that everyone knows their roles, and several others such as RACI and RAPID. Use whichever system makes the most sense for your organization.
I find it best to identify this person early on in a project and make sure it is restated at the start of a meeting (it can be included on the agenda as well), as it helps greatly if you find yourself at a crossroads. This person can unblock you and help the group move forward.
Moving Forward
It may at times feel like meetings are a drag on a software engineering process, but it doesn’t always have to feel this way. There’s something special about collaborating with a group of people who are respectful and working towards a common purpose. Good meetings can provide clarity and save people hours and days of work when they’re headed in the wrong direction. Having clear ownership, documentation, and only the right people in the room can keep many teams in lockstep, even when problems are complex.
Buy the Book
This is just a sample of the kind of content from my latest book coming out soon…
This is a super niche blog post. But it’s been on my list forever to write down because this caused me grief for far too long.
The setup is that you can use WooCommerce to sell things on a WordPress site, of course. If what you’re selling is a physical product, one thing you can do is set that up as print-and-ship on-demand. That’s what I do, for example, with our printed posters and sweatshirts. One company that does that, and the one we use right now, is Printify. It’s not even a plugin, it’s just APIs talking to each other.
That all works fine. The problem I was having? Customers weren’t getting any shipping notifications.
For a long time, I thought this was just something Printify punted on. For example, Printify doesn’t provide customer service to your customers, only to you. So if your customer has a problem, they contact you, and if it seems like it’s a Printify problem, you need to then contact them to figure it out. That’s not my favorite, but it’s understandable, as you are acting as the storefront here and things can go wrong with orders that the store needs to deal with, not Printify.
But no shipping notifications seems bananas. That’s like table stakes for eCommerce. Not to mention you can see shipping information in the Printify dashboard. So it was a lot of…
Customer wonders where order is
Customer is annoyed they didn’t get any shipping notification
Customer emails me
I look up shipping/tracking information
I send to them manually
That’s just not tenable.
The thing is though, it’s supposed to work, and it does through a sneaky little feature of core WooCommerce itself.
So an order comes in, and I can see it:
Once the payment is solid, it’ll kick over to Printify, and I can see the order there too.
Once Printify has tracking information, it becomes available in the Printify dashboard:
Most orders do. Some orders just randomly don’t — although that’s mostly international orders (e.g. from the U.S. to another country)
The trick is that this tracking information doesn’t just stay in Printify. They API it over to the WordPress site as well in the form of a “note” on the order. So you can see it there:
Notes are, in a sense, kind of abitrary metadata on orders. You can just type whatever you want as a note and either add it privately or visibly to the user.
That was all happening normally on my site.
Here was my problem:
My “Customer note” email was turned off.
I was confused I guess because I didn’t really understand the “Notes” idea in WordPress and it wasn’t documented anywhere saying that is how Printify communicates this information. It just dawned on me looking at it for the 100th time. Why that was off? I don’t know. Does it default to off? Did I turn it off because I didn’t understand it, and turning off customer-facing emails I don’t understand felt right at some point? Again, I don’t know. I also maybe just assumed that Printify would email the customer the tracking information because they have that information, as well as the customer email. Who knows.
With it on, though, it works!
Point is: by turning this email on, it went from a ton of very manual customer service work to almost none. So I wanted to get it blogged in case anyone is in this frustrating situation like I was.
It’s CSS-Tricks birthday! Somehow that keeps coming around every year. It’s that time where I reflect upon that past year. It’s like the annual vibe check.
I’m writing this just days after my current home state of Oregon has lifted most of the COVID restrictions. Certainly a very weird feeling. We’re just hitting the state-wide 70% vaccinated level which is the big milestone covered in the news. I thought our little local organic-heavy progressive grocery store would be the last place to go mask-less, but even in there, the vast majority of people are raw-facin’ it, employees included. So it’s not just America’s birthday this year, but a real sign of changing times. Controversy in tow, as there is plenty of evidence the danger is far from over. Definitely gonna hit up some fireworks though. The kid loves ’em.
Well-Oiled Machine
I’d say that’s ^ the main vibe around here from my perspective. The site is in good shape all around. The tech behind it is stable and mostly satisfying. The editorial flow is flowing. The content idea bucket overfloweth. The newsletter goes out on time. The advertising and sponsorship demand is sound. Ain’t any squeaky wheels on this train.
And did you know we have zero meetings? Just light Slack chatter, that’s it. This is a part-time gig for everyone, and we aren’t doing any life-saving work here, so no need to take up anyone’s time with meetings.
Technologically, we’re leaning more and more into the WordPress block editor all the time and it feels like that is a good thing to do here in WordPress land. Every time we have a chance to get more into any current WordPress tech and take advantage of things WordPress does well, it tends to work out.
This is all great because as far as hours-in-the-day go, most of my time is on and needs to be on CodePen. An incredible amount of work lays ahead there as we evolve it.
Things to Get Done
That’s not to say there isn’t work to be done. I’ve got some WordPress scrubbing to do, for one thing. There are a few too many places functionality code is being stored on the site. I’ve completed an audit, but now I need to do the coding work to get it clean again. Things change over the years, WordPress evolves, needs evolve, performance and accessibility considerations evolve, my own taste evolves. Code from 8 years ago needs to evolve too.
One thing I’d really love to get done is to move all the content on the site that really should have been a Custom Post Type to actually be Custom Post Types. Namely screencasts and almanac entries. Right now they are Pages instead, which was fine at the time as it lends itself to a hierarchical structure nicely. But the only reason they aren’t Custom Post Types is because those didn’t exist when I started them. In today’s WordPress, they really should be, and I think it would open doors to managing them better. I’m not sure I have the chops to pull off a conversion like that so I might have to hire out for it.
I’d also like to evolve our eCommerce a bit. I think it’s been going great as we dipped our toes into selling things like posters and MVP membership, and now it’s time to make all that stuff better and more valuable since it’s a proven win. For example, I’m working on making sure the book is downloadable in proper eBook formats, that’ll be a value-add for members. I’ve started thinking about what more we can do with the newsletter as well since those are so hot these days, and I’m a fan.
Social Media Cards
While social media isn’t a major focus of ours, we do tend to make sure Twitter is in good shape, as we have that sweet handle @css. I’m pretty hot on the idea that sites (content sites especially), should have nice social media images. Fortunately, thanks to Social Image Generator and some custom code, ours are in good shape. I still smile looking at them as they are so damn distinct now. WP Tavern did a nice writeup on the plugin.
There are five different possibilities for social cards now we can use.
This is the default. It defaults to the post title, but we can override that.
If the post has a featured image, it will be incorporated into the social media image like this.
If we add a quote to a meta field, we’ll get this special quote card design.
We can turn off the generated social media card and have it just use the featured image as the card.
If we turn off the generated social card and don’t have a featured image, it falls back to this generic card.
Sponsors
I’m incredibly blessed that we have the same four major sponsors as we’ve had the last few years:
Automattic: WordPress is at the heart of this whole site. I’m so pleased to get to have Automattic as a sponsor, who not only create all kinds of important software for WordPress that we use here, like Jetpack and WooCommerce, but are big contributors to WordPress itself. I like that the site can be a living testament to what you can do with WordPress.
Frontend Masters: There is no A to Z learning path here on CSS-Tricks. If you want true curriculum to level up your skills, that’s what Frontend Masters is for. I couldn’t recommend any learning platform more, which is why I’m so happy to have them as our official learning partner and enthusiastically point people there.
Netlify: The Jamstack is a good movement for the web and literally nobody does it better than Netlify. They have pioneered so many good ideas it’s incredible. It’s easy to look at the industry and see even huge companies scramble to do what they’ve been doing for years.
Flywheel: I’m a believer in happy path web hosting. Use hosts that specialize in what you’re doing. This site is WordPress and I don’t think there is a better hosting option for WordPress than Flywheel. And that’s without consider that they also make Local, of which there is no better local development story for WordPress.
Design
We’re about a year and a half into v18, and it has certainly evolved quite a bit since its launch. While it’s feeling solid now, I’ve started to get the redesign itch and have been saving design inspiration for v19. I imagine it’ll happen over the slower holiday season as it tends to. I have a feeling it’ll be a stripping-down sort of design heading back to less colors and more typography-driven approach that can support themes in a way I never have. But we’ll see!
Analytics
It’s largely the same story as the last 3-4 years. Always hovering just a smidge north of 8m page views a month. A perfectly healthy number for such a niche site. But also a constant reminder how difficult the content game is. You’d think a constant stream of content creation would grow traffic up and up over time, particularly since our technical content usually has a decent shelf-life. But at some point, you have to keep creating content and keep working on a site just to maintain what you have. Meaning older content slowly drives less traffic and new content needs to step up and fill the gap. At least that’s one interpretation of what’s going on—I’m sure the complete story is much more intricate (SEO, competition, saturation, content blockers affecting numbers, etc).
The name?
I ain’t gonna up and change anything, but the name “CSS-Tricks” has been so hokey for so long. Every time I see some other brand pull of a daring name change, I’m a little jealous. Would it be worth it for CSS-Tricks? The potential benfits being: a new name could usher in fresh interest in the site, be a catalyst for other change, and be less of a jarring mismatch between what we actually publish and what people might expect us to publish based on the name. I’d have to do a lot more thinking and research to be able to pull it off. If the domain changes, even with perfect redirects, are there still serious SEO implications? How could I minimize the confusion? Is there a chance in hell a change has more upsides than downsides?
Get that desk more cuter, fam. Amy (@sailorhg) has this perfectly cute minisite with assorted desktop backgrounds, fonts, editor themes, keyboard stuff, and other accessories. These rainbow cables are great.
Get that desk more cuter, fam. Amy (@sailorhg) has this perfectly cute minisite with assorted desktop backgrounds, fonts, editor themes, keyboard stuff, and other accessories. These rainbow cables are great.