# SCSS Code Style

ScandiPWA follows the BEM methodology to write styles. In addition, there are some guidelines to help you write more maintainable stylesheets.

We strongly recommend you use [Stylelint](broken://pages/-MOVDCW03Ud-lKz1G5Il) to check your code style. This article was written to help you understand the code style rules we enforce and write better code.

## Avoid Non-BEM Selectors

{% hint style="danger" %}
Avoid using selectors that aren't Block-Element-Modifier classes:

{% code title="component/CheckoutOrderSummary/CheckoutOrderSummary.style.scss (fragment)" %}

```css
.CheckoutOrderSummary {
    &-CartItemDescription {
        margin-top: 5px;

        p {
            font-size: 1.1rem;
            line-height: 1.5;
        }
    }
}
```

{% endcode %}

Potential issues:

* As code becomes more complex, it can become unclear what role the `p` plays in the app. A well-named BEM class would describe its purpose better
* Unnecessary coupling: JavaScript code is now forced to use a `<p>` element. If you want to rewrite the component to use a `<div>` instead, you would have to update the styles.
* Unnecessary [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): Having an additional selector element will increase the specificity and make the styles harder to [override in `.override.style.scss` files](/developing-with-scandi/override-mechanism/extending-styles.md#partially-overriding-a-components-styles).
  {% endhint %}

{% hint style="success" %}
Instead, it is recommended to assign a new BEM class to the element you want to style. Then, you can select it properly:

```css
.CheckoutOrderSummary {
    &-CartItemDescription {
        margin-top: 5px;
    }
    
    &-CartItemDescriptionContent {
        font-size: 1.1rem;
        line-height: 1.5; 
    }
}
```

{% endhint %}

## Minimize Nesting

In some cases, you might need to style one Block differently depending on whether it is a child of another block.

{% hint style="danger" %}
Avoid nesting selectors - don't select a block nested inside another block:

```css
.Button {
    margin: 5px;
}

// this is discouraged
.ContactForm .Button {
    margin: 10px;
}
```

This is discouraged for several reasons:

* `Button` styles now contain selectors from another component. This causes coupling, which will result in issues if the `.ContactForm` block is renamed
* The selector has higher specificity, making it harder to override.
  {% endhint %}

{% hint style="success" %}
Instead, consider using a variable to customize your styling:

{% code title="Button.style.scss" %}

```css
:root {
    --button-margin: 5px;
}

.Button {
    // by default, a value of 5px will be inherited from :root
    margin: var(--button-margin);
}
```

{% endcode %}

{% code title="ContactForm.style.scss" %}

```css
.ContactForm {
    // we can set the variable lower in the hierarchy to override it
    --button-margin: 10px;
}
```

{% endcode %}

Now, each component is responsible for its own styles only, and the specificity is still low.
{% endhint %}

{% hint style="info" %}
In this case, another possible solution would be to use a Modifier:

```css
.Button {
    margin: 5px;
    
    &_margin_large {
        margin: 10px;
    }
}
```

Now, the button could take a prop to specify the margin size and add it as a modifier to the Button Block. Then, the ContactForm would have to pass a value to this prop indicating that the button should have a larger margin.
{% endhint %}

## Prefer Mobile-First Styling

Mobile-first styling means that you are encouraged to start with mobile styles. When mobile styles are complete, you can use the `@include desktop` directive and other [breakpoints](/structure/building-blocks-summary/global-styles.md#breakpoints) to adjust the styling for larger viewports.

## Avoid Magic Numbers

You should avoid hard-coding numbers when their reasoning is not obvious. Make values re-usable and understandable by using CSS variables.

{% hint style="danger" %}
Avoid hard-coded values:

```css
.NotificationList {
    position: fixed;
    top: 110px;
}
```

Issues:

* Unclear where the value 110 is coming from
* The layout can break if some values are changed
  {% endhint %}

{% hint style="success" %}
Instead, use variables, and combine them with `calc` if necessary:

```css
.NotificationList {
    position: fixed;
    top: calc(var(--header-height) + var(--breadcrumbs-height) + 20px);
}
```

Advantages:

* Intentions are more clear
* Variable values can be safely changed to adjust the layout
* Each value is re-usable.
  {% endhint %}

## Use Round Numbers

Unless you need to produce a pixel-perfect design, we recommend using values rounded to the nearest 5px, avoid unnecessary decimal digits, and consider how much precision browsers can actually display.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.scandipwa.com/structure/code-style/scss-code-style.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
