Refactor when needed

As much as possible, we want to have a good plan from the very beginning before diving in to a project, because that should mean we won't have to refactor anything.

However, you might realize at one point that you made a mistake, or that you could have done something better.

Often, what happens then is we shrug our shoulders and say "next time".

But all that does is increase the technical dept in the current project, and you probably won't remember next time either.

If you take a bit of time to do a refactor, you'll both improve the code of the project you're working on now and have a better chance to remember the next time around as well.

An example

This project only has one style of button, so we didn't do anything too fancy when setting it up, but it's possible that down the road, you need an orange button, or a bigger or smaller version of the button.

We could update a few of our properties:

.button {
  color: var(--button-text, var(--text-high-contrast));
  background-color: var(--button-bg, var(--background-accent));
  border-radius: var(--button-br, var(--border-radius-1));
}

.button:hover,
.button:focus-visible {
  color: var(--button-text-hover, var(--text-high-contrast));
  background-color: var(--button-bg-hover, var(--background-accent-light));
}

And then make modifiers, either with modifier classes or attributes, depending on how you've been working:

.button--brand {
  --button-bg: var(--clr-brand);
  --button-bg-hover: var(--clr-brand-light);
  --button-text-hover: var(--background-extra-dark);
}

/* or */

.button[data-theme="brand"] {
  --button-bg: var(--clr-brand);
  --button-bg-hover: var(--clr-brand-light);
  --button-text-hover: var(--background-extra-dark);
}

And, of course, you could build these out a lot more than this!

Readability

One issue with having custom properties fall back to other custom properties is it can be hard to read.

The advantage of this is allowing for easy customization though, like we saw with our cards in our guide, where we did this:

.mushroom-guide {
  --card-title-font-size: var(--font-size-lg);
  --card-title-color: var(--text-high-contrast);
  --card-gap: 0.75rem;
}

Having the fallbacks set up like this is very handy, but if you want more encapsulated components, you can also do this:

.button {
  --button-text: var(--text-high-contrast);
  --button-bg: var(--background-accent);
  --button-br: var(--border-radius-1);
  --button-hover-text: var(--text-high-contrast);
  --button-hover-bg: var(--background-accent-light);

  color: var(--button-text);
  background-color: var(--button-bg);
  border-radius: var(--button-br);
}

.button:hover,
.button:focus-visible {
  color: var(--button-text-hover);
  background-color: var(--button-bg-hover);
}

We can easily overwrite these directly on our buttons with modifiers, but if we set things up this way, you cannot modify things on a parent or other ancestor.

For buttons, I think that's worth the trade-off, but for things like our cards, as we've seen, it can be handy to be able to tweak things.