The base styles are defined in the styles
directory inside the theme folder and imported to be combined in styles/main.scss
. For you to modify the original styles of a theme there are 3 main ways to approach this, you can:
app/style
that define the main look of the application. These define global settings, such as SCSS variables (style/abstract/_variables.scss
), media query definitions (style/abstract/_media.scss
), base styling for some HTML elements (style/base
), CMS content styling (style/cms
), and more. If you want to make global styling changes to these files, you can override them.<component>.style.scss
. If you wish to completely change the look of a component, you can replace these styles with your own.You can choose from these options and have files automatically created when overriding components with VSCode plugin or ScandiPWA CLI.
How to override components with VSCode plugin?
How to override components with Scandiweb CLI?
The base styles are defined in the styles
directory, and imported in styles/main.scss
. In order to override a base style file, you need to copy over the chain of files that is used to import it.
For example, suppose we want to change the main theme color to an ocean blue. The primary color is defined in style/abstract/_variables.scss
. Copy over this file to avoid missing any variables, and make the desired changes:
$white: #fff;
$black: #0a0a0a;
$default-primary-base-color: #2387f2; // changed the color here
$default-primary-dark-color: #1259d4; // and here
$default-primary-light-color: #42bdf7; // and here!
$default-secondary-base-color: #eee;
$default-secondary-dark-color: #929292;
$default-secondary-light-color: #f8f8f8;
$font-muli: 'Muli', sans-serif;
$font-standard-size: 12px;
$font-mobile-size: 14px;
We also need to copy over the file that imports _variables.scss
for the override to work. By inspecting the styling files, we can see that style/abstract/_variables.scss
is imported in style/abstract/_abstract.scss
, which is itself imported directly from style/main.scss
. Hence, we need to copy over _abstract.scss
and main.scss
to their respective directories in our theme.
We can check that the theme's primary color has been successfully overridden:
Sometimes you may want to completely restyle a component, ignoring all original styles. For example, suppose we want to create an entirely new design for the CategoryPaginationLink
component. All we need to do is create a stylesheet with the same path as the stylesheet from the parent theme we want to override. In this case, create a file in component/CategoryPaginationLink/CategoryPaginationLink.style.scss
with the following contents:
:root{
--category-pagination-link-size: 50px;
--category-pagination-link-text-size: 30px;
}
.CategoryPaginationLink {
// configure layout and center text
display: block;
text-align: center;
size: var(--category-pagination-link-text-size);
line-height: var(--category-pagination-link-size);
// set a circular shape with border-radius
width: var(--category-pagination-link-size);
height: var(--category-pagination-link-size);
margin: 6px;
border-radius: var(--category-pagination-link-size);
// white text on a blue background
background: var(--primary-base-color);
color: #fff;
// indicate hover/active state
transition: opacity 100ms ease-out;
opacity: 0.7;
&:hover,
&:focus,
&_isCurrent {
opacity: 1;
}
}
With this override, any import of the CategoryPaginationLink
stylesheet will resolve to our custom file. Hence, our stylesheet will be the one to be included in the final CSS file, resulting in this look:
If you wish not to confront the original styles completely, and just want to change minor aspects of the component's styling, you can keep the original styles instead, and override some of them with a new style file.
Let's use another example, Consider we want to change the style of the heading of MyAccountOverlay
component, we want to make the text "Sign in to your account" italic.
Create a stylesheet with the same path as the stylesheet from the parent theme we want to override with a small exception:
<aside>
➡️ We can't keep the original name of the file, because then we will override it completely as shown in the previous section. The naming convention for partially overriding stylesheet files in ScandiPWA is to add .override
to the file name.
</aside>
In this case, that file will be in: src/component/MyAccountOverlay/MyAccountOverlay.override.style.scss
instead of: src/component/MyAccountOverlay/MyAccountOverlay.style.scss
Add the code inside the new created file:
.MyAccountOverlay {
&-Heading {
font-style: italic;
}
}
Styles in ScandiPWA are typically imported from the .component
file, so we have to override the MyAccountOverlay.component.js
by creating the file with matching pathname with the original component, in this case, it'll be in src/component/MyAccountOverlay/MyAccountOverlay.component.js
.
Add these imports to your new file:
// import the original component so that base styles are applied first
import 'SourceComponent/MyAccountOverlay/MyAccountOverlay.component';
// import our modified styles to override some of the default ones
import './MyAccountOverlay.override.style.scss';
// re-export all the original exports from the parent theme untouched
export * from 'SourceComponent/MyAccountOverlay/MyAccountOverlay.component';
export { default } from 'SourceComponent/MyAccountOverlay/MyAccountOverlay.component';
To override a ScandiPWA component’s style through a plugin in your extension, you can simply import your <COMPONENT>.plugin.override.style.js
file in your plugin.
For example:
ProductPrice.plugin.override.style.scss
.ProductPrice {
&-Price {
border-top: 1px solid var(--grey-color);
display: flex;
justify-content: space-between;
}
}
ProductPrice.component.plugin.js
import './ProductPrice.plugin.override.style';
const doSomething = (args,callback) => {
callback(...args);
// do something...
return something;
}
export default {
'Component/ProductPrice/Component': {
'member-function': {
renderSummary: doSomething
}
}
};
If the component does NOT exist in the project’s components, then this will be enough to override the source component, without the need to import and re-export the original component.
<aside> ➡️ If it does exist in the project’s component, a different but simple set of steps is needed, as the project’s component style will override your plugged style.
</aside>
In some cases, when developing an extension, you’ll notice your project may already have overriden components, and that you must override them to implement some extension-specific stylization.
To achieve this, you can override the project’s component through a plugin, by creating a component to firstly load the original styles from the project’s component, and then load your own style override.
<EXTENSION-NAME>/src/component/CartOverlay/CartOverlay.component.js
// import the original project component so that base styles are applied first
import 'Component/CartOverlay/CartOverlay.component';
// import our modified styles to override some of the default ones
import './CartOverlay.override.style.scss';
// re-export all the original exports from the parent theme untouched
export { default } from 'Component/CartOverlay/CartOverlay.component';
<aside>
🚨 Notice that when overriding a project component, you should use Component
instead of SourceComponent
! This is because the project component already overrides SourceComponent
.
</aside>
Then you can force the original container to render your own component through a plugin:
<EXTENSION-NAME>/src/plugin/CartOverlay.component.plugin.js
// import your own modified component
import CartOverlayComponent from '../../component/CartOverlay/CartOverlay.component';
const overrideCartOverlayStyles = (args, callback, instance) => {
// desconstruct container's functions and props from instance(original class instance)
const { containerFunctions, containerProps } = instance;
return (
<CartOverlayComponent
{ ...containerFunctions }
{ ...containerProps() }
/>
);
};
export default {
'Component/CartOverlay/Container': {
'member-function': {
render: overrideCartOverlayStyles
}
}
};