# Customizing CSS classes

**Styling in the Loki Checkout is handled via Tailwind CSS classes - for both Hyvä and Luma themes! This means that the PHTML templates actually contain the CSS classes to keep in the Tailwind CSS build, which again means that - normally - template overrides would be needed for the simplest thing. Loki Checkout tries to keep template overrides to a minimum. It does so by adding clever PHP utilities that allow you to modify various CSS classes in the XML layout instead.**

## Using the `$css()` utility
In every single PHTML template of the Loki Checkout, a new PHP variable `$css` is added which is actually an instance of the class `\Loki\CssUtils\Util\CssClass` (part of the [`Loki_CssUtils`](/dev/modules/Loki_CssUtils) module) which is invokable, as in, it behaves like a function:

```php
$css('foobar')
```

> Note that you can use the Loki_CssUtils module separate from LokiCheckout and LokiComponents. You can use it anywhere you like.

The CSS classes you would add to this function will be outputted, unless they are actually overwritten in the XML layout. A real-life example usage of the utility might look like this:

File `example.phtml`:
```php
<div class="<?= $css('field w-auto relative') ?>"></div>
```

By default, this will simply output the CSS classes as-is in the browser:
```html
<div class="example field w-auto relative"></div>
```

Note that an additional CSS class `example` is automatically added as well, based on the XML layout name of the block that defined this template. (This only works if the scope is `block` which is explained later on.)

File `loki_checkout.xml`:
```xml
<block name="example" template="LokiCheckout_Core::example.phtml" />
```

## Extending CSS classes
However, with the example above, we can also add new values easily as such. Take for example the `prefix` block:

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <body>
        <referenceBlock name="loki.checkout.shipping-step.shipping-address.prefix">
            <arguments>
                <argument name="css_classes" xsi:type="array">
                    <item name="block" xsi:type="array">
                        <item name="color" xsi:type="string">bg-zinc-100 border border-zinc-200</item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

Within the item definition, the name `color` is actually not important, only the value of the item is important. And you can see that one item definition is able to hold multiple CSS classes.

Now the HTML will look like the following:
```html
<div class="example field w-auto relative bg-zinc-100 border border-zinc-200"></div>
```

In short, first the block identifier, then the default CSS (which was passed from the PHTML template) and then the additional CSS from the XML layout.

## Overriding CSS classes
What about overriding CSS classes? For this, it is important to know that the item name `default` can be used to override the default CSS (which was passed from the PHTML template).

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <body>
        <referenceBlock name="loki.checkout.shipping-step.shipping-address.prefix">
            <arguments>
                <argument name="css_classes" xsi:type="array">
                    <item name="block" xsi:type="array">
                        <item name="default" xsi:type="string">field w-100 relative</item>
                        <item name="color" xsi:type="string">bg-zinc-100 border border-zinc-200</item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

Now the HTML will look like the following:
```html
<div class="example field 100 relative bg-zinc-100 border border-zinc-200"></div>
```

## Scoping CSS
What if you want to use the `$css()` utility multiple times in the same PHTML template? Then you need to add a scope. By default, the scope `block` is being used (`$css('foobar', 'block')`), but you can refer to other scopes easily. The following example defines a new scope `inner-span`:

```php
<div class="<?= $css('field w-auto relative') ?>">
    <span class="<?= $css('text-xl', 'inner-span') ?>"></span>
</div>
```

Now, within the XML layout, the CSS classes of the `inner-span` scope can be extended like follows:

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <body>
        <referenceBlock name="loki.checkout.shipping-step.shipping-address.prefix">
            <arguments>
                <argument name="css_classes" xsi:type="array">
                    <item name="inner-span" xsi:type="array">
                        <item name="default" xsi:type="string">text-2xl</item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

Scopes are only relevant when it comes to overriding or extending CSS classes via the XML layout.

> Sometimes a CSS class is placed outside of the `$css()` statement. Most of the times, this is dealing with a mandatory CSS class to guarantee behaviour of a child HTML element (like the CSS class `relative` when using the `loki-checkout.utils.loader-overlay` block).

## Extending CSS classes via the global block
If you are making a lot of changes to CSS classes of blocks, even the mechanism mentioned so far could lead to a lot of code duplication. A final resort is to make CSS class changes via the global block `loki-components.css_classes` instead. This block is never shown on the page, but is simply used as a temporary storage for CSS classes. Each `argument` represents a block ID (for example `loki-checkout.example`) with all of the `item` configurations below that being CSS class sections as explained above:

```xml
<referenceBlock name="loki-components.css_classes">
    <arguments>
        <argument name="loki-checkout.example" xsi:type="array">
            <item name="block" xsi:type="array">
                <item name="foobar" xsi:type="string">foobar</item>
            </item>
        </argument>
    </arguments>
</referenceBlock>
```

## Extending CSS classes for PHTML templates
To make things even more flexible, default CSS classes can be set for specific templates. Take for example the PHTML template `LokiCheckout_Core::form/field.phtml` which is actually reused by every LokiComponent representing a field. Instead of making changes for every single form field, you could also just apply the CSS changes to the PHTML template. And then later override or extend the CSS classes for specific block instances. 

For this, the following mechanism applies. The original template `LokiCheckout_Core::form/field.phtml` is stripped from its module prefix (`form/field.phtml`). Next, the PHTML suffix is removed (`form/field`) and slashes are turned into dots (`form.field`). This identifier is then prefixed with `loki-components.defaults.`. The final block ID is `loki-components.defaults.form.field`. If this block exists in the layout, it is taken into account while parsing CSS classes.

```xml
<block name="loki-components.defaults.form.field">
    <arguments>
        <argument name="css_classes" xsi:type="array">
            <item name="block" xsi:type="array">
                <item name="grid" xsi:type="string">col-span-6</item>
            </item>
        </argument>
    </arguments>
</block>
```

And ofcourse, you can add in the XML layout a `referenceBlock` instruction to make changes to this.

## Using the `$style()` utility
Besides the `$css()` utility, the `Loki_CssUtils` module also offers a `$style()` to generate inline styling:

```php
<div style="<?= $style('display:block') ?>"></div>
```

Just like CSS classes, inline styles can also managed via XML layout. In this case, it is not a complex array but just a simple string:

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
    <body>
        <referenceBlock name="loki.checkout.shipping-step.shipping-address.prefix">
            <arguments>
                <argument name="css_styles" xsi:type="string">display: none</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

Within our own extensions, we try to limit the use of CSS styles to the definition of CSS properties, like `--loki-col-span:12`, `--loki-md-col-span:12` and `--loki-order` which then used again in CSS classes.

<div class="notice">More docs coming soon</div>
