When To Create CSS Parts

I was recently asked a really good question on Twitter: when shouldn't an element be a CSS Part?

I've spent a lot of time building web components, most of which are intended for design systems, and my answer is pretty straight-forward.

Every part you expose is an API that you're committing to supporting, so it should be very intentional. Consider a component that uses a complex structure that you later need to refactor. If you've exposed everything as a part, your internals are locked down and breaking changes will be harder to avoid.

We're in a transitionary period where developers are starting to consume custom elements, many for the first time, and the concept of a shadow DOM frustrates them because they can't style things the way they're used to.

That's the feature.

You don't have to worry about internals. All the customizations are built in and exposed through attributes, custom properties, and CSS parts. I think of it not as a flat chunk of HTML I'm adding to the page, but as unique components with APIs that control their appearances and behaviors.

We As Developers #

I often hear developers lament, "but I just want to style [some simple thing]!" This is a valid frustration if the custom element isn't designed well. You can easily run into things that aren't exposed that probably should be!

It means we, as custom element authors, must think more about our component APIs. We need to consider composition, portability, and reusability. We can't just throw some HTML and CSS together and call it done. We have be more intentional with the things we create.

I don't think that's a bad thing. The Web has always been a sort of wild west where anything goes. HTML and CSS, by design, are very forgiving. But when you're creating components — building blocks that serve as critical pieces of an application's foundation — you really need to think them through.

Think of this as a feature, not a limitation. Be very explicit with the things you expose. Think of CSS parts and custom properties as part of your component's public API, because that's exactly what they are.