Skip to content

Commit

Permalink
new: css/dynamically-change-styles-from-html-or-jsx.md
Browse files Browse the repository at this point in the history
  • Loading branch information
byt3h3ad committed Dec 28, 2023
1 parent 6713e79 commit fd4a64a
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions css/dynamically-change-styles-from-html-or-jsx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Dynamically change styles from HTML or JSX

(No, it's not Tailwind.)

I wanted a button on my website to be "RSS orange" even though that color wasn't anywhere else in my color scheme. Hardcoding that within the button component itself felt overly specific; the button should mostly be agnostic to what's inside of it. But the button component encapsulated its own markup and styles, and I didn't want to break that encapsulation by reaching in from outside to override things.

The solution, surprisingly, was to use inline styles! Not by setting any properties, but by setting a [custom property](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) — often known as a CSS variable.

```html
<button className="button" style="--accent: #ff6600">Subscribe via RSS</button>
```

That sets the custom property `--accent` to `#ff6600` within **that specific button element**. The corresponding CSS might look something like this:

```css
.button {
background-color: var(--accent, var(--color-primary));
}
```

The key is to specify a [fallback value](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#custom_property_fallback_values) when accessing `--accent`. So by default, everything with the class `button` would have a background color of `--color-primary`**except** when `--accent` is defined, in which they'll use `--accent`.

This pattern pairs particularly well with component-based frameworks like React, where it's common to change behavior by exposing props. A `Button` component using this pattern might look like this:

```jsx
function Button({ accent, children }) {
// only set `--accent` if it's not an empty string
// otherwise it'll be set to the literal string "undefined" and everything will break
const style = accent ? { "--accent": accent } : {};

return (
<button className="button" style={style}>
{children}
</button>
);
}
```

To use it, just pass something to the `accent` prop:

```jsx
<Button accent="#ff6600">Subscribe via RSS</Button>
```

0 comments on commit fd4a64a

Please sign in to comment.