Styling

Components (including views) can be styled and usually come with their own stylesheet. As our components are web components, they use the Shadow DOM which has implications when it comes to styling. The general rule is that component styles are completely encapsulated and other rules cannot pierce into the Shadow DOM for your component.

Note

All of our styles are built using SASS. You read more about SASS on their documentation. You will not have to do anything to setup SASS, this is all done for you. You just merely need to create the .scss files for your component.

Let's see how styles are declared on a component. There are three ways to do this:

1. Via Component Declaration

The newest and probably easiest way is via component declaration as below:

@component({ tag: "wc-my-first-component", styles: [ require("./my-first-component.scss") ] })
export class MyFirstComponent extends BaseComponent<MyAppManager> {

    //...Component code
}

The styles array in the @component decorator argument is the first place you can add styles to a component. For most components, this is enough. You can place one or more stylesheets here if needed, but usually each component will have only one.

2. Via Explicit Inclusion

The second method is the original way we used to include stylesheets and is done by including the following function inside your component code:

componentStyles(): JSXElement {

    return (
        <style>
            { require("./my-first-component.scss") }
        </style>
    );
}

In older versions of apps built inside the framework, you will see that this is the only way used to include styles. This is still useful (not just for backwards compatibility) because it happens inside the instance of each component and therefore you can change / alter styles based on state.

In general, if you only ever need one stylesheet for your component, then the component declaration method is the preferred and cleaner way.

3. Via Inline Styles

Inline styling is possible too and may be used in combination with the other two methods. Generally, this is only used when you need to need to change style rules based on state and is not used to set the initial styling of a whole component.

componentMarkup(): JSXElement {

    const styles: CSSStyleDeclaration = buildStyles({

        color: "red",
        marginTop: "10px"
        // ... more rules
    });

    return <p style={ styles }>This is some text</p>
}

The main thing to note here is that inline styles generally need to be wrapped within the buildStyles function in order to pass the type checking.

Useful Style Pointers

Styling can look a little bit different than what you may be used to so here are some pointers that are worth noting.

Using :host Selectors

The Shadow DOM is a little different but it boils down to wrapping your rules with the :host selector. Let's look at a quick example:

:host {

    div.container{

        background-color: "blue";
    }
}

If you have a component with the HTML tag of my-first-component, then the above is essentially the same as:

my-first-component {

    div.container{

        background-color: "blue";
    }
}

Using :host is a must if your app is going to be deployed in a Shadow DOM supported environment. If Shadow DOM isn't supported (for example, in IE11), then use the second method.

Attribute Selection with :host

Attribute selection is a little different for :host selectors. See:

:host([has-my-attribute]) {}

You basically have to wrap the selector in ([]).

Styling for Browsers which don't support Shadow DOM

There's no real easy way to do this. Our solution at the minute is to create a second stylesheet that you import which will not use :host selectors. You can then use style declaration as below with the isIE11 util function:

@component({ 
    tag: "wc-my-first-component",
    styles: [
        isIE11()
            ? require("./my-first-component-ie11.scss")
            : require("./my-first-component.scss")
    ];
})

Rule Cascading

Whilst style rules cannot pierce the Shadow DOM, you can pass styles down through cascading if you want to. For example:

div {

    my-first-component {

        color: red;
    }
}

If color: inherit is set inside the rules for my-first-component then this will pick up the value of red.

CSS Variables

CSS Variables are the only way to pierce the Shadow DOM and we used this in many apps. Usually, there is a theme.css file inside the build/css/ directory which will have a few CSS Variables set for common values.

These can then be used inside your component stylesheets by using the syntax: color: var(--my-css-variable-name);

By default, you should build your styles to make use of CSS variables as this makes features such as theming or night mode trivial to implement.

results matching ""

    No results matching ""