hypnagaga/src/docs/guides/customising-with-scss.mdx
hobbes7878 ef578b086a logos
2024-11-19 21:34:32 +00:00

92 lines
3.4 KiB
Text

import { Meta } from '@storybook/blocks';
import { parameters } from '../utils/docsPage.js';
import startImg from './imgs/scss-start.png';
import highlightImg from './imgs/scss-highlight.png';
import inspectorImg from './imgs/scss-inspector.png';
import changeImg from './imgs/scss-change.png';
import testImg from './imgs/scss-test.png';
import winningImg from './imgs/scss-winning.png';
<Meta
title="Guides/Customising components with SCSS"
parameters={{ ...parameters }}
/>
# Customising components with SCSS
One of the most powerful ways to customise components isn't props or, even, Svelte.
<p className="sbdocs-p">
<span className="highlight bold">
It&rsquo;s SCSS and your web inspector!
</span>
</p>
## How's that??
Let's say you wanted to change our `BeforeAfter` component. You want the text overlays to be at the bottom of the image instead of the top like this:
<img src={startImg} width="600" />
The first thing you should do is <span className="highlight">check out the elements you want to change in your web inspector</span> and see if CSS can make the change you want.
<img src={highlightImg} width="300" style={{ margin: '0 0 1rem' }} />
<img src={inspectorImg} width="100%" />
In our case, we want to change the absolute position of those elements. To test that'll actually work, we can <span className="highlight">try it directly in the inspector first!</span>
<img src={changeImg} width="500" style={{ margin: '0 0 1rem' }} />
<img src={testImg} width="600" style={{ margin: '0 0 1rem' }} />
Now that we know we can change what we need through CSS it's time to write some SCSS, either in your `global.scss` file or directly in a component like `App.svelte`.
First, let's look at the class of the style rule we changed in the inspector:
`figure.before-after-container.s-khJY-w4TYkp5 .overlay-container.before.s-khJY-w4TYkp5`
One thing we always need to do is <span className="highlight">strip out any Svelte class names</span>, i.e., those weird `.s-khJY-w4TYkp5` classes. Why? Those are random classes Svelte adds to CSS, and we can't guarantee they won't change.
That leaves us with:
`figure.before-after-container .overlay-container.before`
But we need our style rule to _beat_ the original style in the CSS cascade, and right now, it's less specific without those class names we stripped.
The easiest way to make sure your style rule wins out is to <span className="highlight">add an ID either directly to the element or to a parent</span>. In our case, let's add an ID through the `BeforeAfter` `id` prop. Now we can use it! (For extra credit, though, we'll drop the `.before` so our new style rule applies to _both_ overlays.)
```scss
figure#my-before-after .overlay-container {
bottom: 0;
}
```
Now our selector is more specific. We win!
If you don't see a way to add an ID through a component's props, then just wrap the component in a `div` in your code:
```svelte
<div id="my-before-after">
<BeforeAfter />
</div>
```
... and use that, instead!
```scss
div#my-before-after figure .overlay-container {
bottom: 0;
}
```
We can <span className="highlight">confirm the new style rule is winning by looking at its order back in our web inspector!</span>
<img src={winningImg} width="500" style={{ margin: '0 0 1rem' }} />
Done!
#### Can I just... `important!` it?
Yep, as a last result. Just be sure your style rule is **very specific** and not something generic that might apply to other elements like `div.container`.