Customizing Vuero
Philosophy
Vuero is built to be an extremely modular and flexible product. Layouts have been destructured so you can switch the entire layout live, without reloading the page. Therefore, page inner content is considered as a component that gets injected in the currently active layout.
Vuero ships with a Quickstarter project. The Quickstarter is a smaller project that contains only what you need to get started with a lighter and less overwhelming codebase. The recommended way of working is to open both projects, and start copying and pasting what you need from the main Vuero project to the Quickstarter project.
Hybrid Sass
my-vuero-quickstarter-project/
├── src/
│ ├── scss
│ │ ├── abstracts
│ │ ├── bulma-generated
│ │ ├── components
│ │ ├── css-variables
│ │ ├── elements
│ │ ├── extensions
│ │ ├── layout
│ │ ├── pages
│ │ ├── vendors
│ │ └── main.scss
│ └── main.ts
└── index.html
Since the version 2.0.0
, Vuero comes with a great paradigm change, in terms of Sass implementation. While everyone is familiar with traditional Sass variables like $color
, we chose to drop this format to take advantage of the power of native CSS-vars
. To support this, we had to make several major changes in the way we handle the compilation of the different color palettes.
The main Bulma framework is built with traditional Sass variables and does not support CSS-vars. We had to find a solution for this. Therefore, we decided to enhance our existing Bulma package with this bulma plugin: https://github.com/wtho/bulma-css-vars. This plugin fully supports CSS-vars and patches the initial Bulma code base, making possible this implementation.
There are 2 new SCSS subfolders in Vuero 2.0.0
: scss/bulma-generated/
and scss/css-variables
. The first one is automatically rendered by a NodeJS utility and is in charge of generating all the Bulma variables, based on your configuration.
Changing the main color
If you need to change the Vuero main color, you need to go through a short compilation step. The main color is generated from an HSL format. This means that wou will need to define your vuero primary color in HSL format for it to work. Here are the different steps you need to go through:
- Choose a primary color for your project. It can be in hex or rgb format, it doesn't matter. Let's go for the example with a purple color like
#6621cf
. - In any colorpicker of your choice, transform your color into an HSL color with a value for each attribute, Hue, Saturation and Luminance. In our case this would result in
264°, 73%, 47%
. - Open
vuero/bulma-css-vars.config.js
. In that file replace the values of theprimary: hsl(153, 48, 49)
block with the values you got one step earlier. You can also change the default values of some basic Bulma variables likedark
,link
,info
etc... - Once you're done with that, run the
pnpm build:update-bulma-colors
script. - Change the value of the
primary
variable insidevuero/src/scss/css-variables/_colors.scss
to complete the color setup. - Tada! You are now done and all your new colors have been generated for you.
TIP
Use color picker in https://vuero.cssninja.io/elements/colors to preview and copy colors snippets!
CSS vars syntax
CSS variables use a different syntax than Sass variables. Declaring a new CSS variable is like this:
Declaration
// :root is an alias for html element but with higher priority
:root {
--myVariable: #fff;
}
// we can override the variable value inside a class scope
.my-red-variable {
--myVariable: red;
}
<!-- we can also override the variable value inside a style scope -->
<span style="--myVariable: blue">
<!-- ... -->
</span>
Usage
.my-variable-color {
color: var(--myVariable);
}
Overriding CSS vars
CSS variables are very flexible and can be overriden from almost everywhere, without affecting other components. For example, let's say that you have a component called <SuperButton></SuperButton>
and that component has a scoped style attribute (<style lang="scss" scoped></style>
), meaning the styles are strictly scoped to that same component. You can override the base --primary
variable inside the component without affecting any other one outside the scope of this one. For example, you can do:
<!-- SuperButton.vue -->
<template>
<button class="super-button">
<!-- ... -->
</button>
</template>
<style lang="scss" scoped>
.super-button {
--primary: blue;
}
</style>
Other Sass files
Vuero relies on the powerful Sass features and a modular structure, letting you handle complex styles in a breeze. You need to import all the SCSS partials into your core file. This is how scss files are organized. Partial SCSS file names always start with an underscore like this: _button.scss
. They act as chunks of code that you can import only if you need them. Of course some of them are mandatory for the project to work. Vuero is a UI kit in wich each SCSS file serves a different purpose:
- abstracts: holds all files related to mixins, default global styles and other typography settings.
- components: holds all files related to Vuero Components. Each component type has its own file.
- Elements: holds all files related to Vuero Elements. Each element type has its own file.
- layout: holds all basic and mandatory layout files. The project will break if you ommit one of those files.
- pages: holds all the specific styles for each demo or group of demos.
- vendors: holds all vendor CSS styles.
Import styles with Vite
In order to load stylesheets into our application (e.g if you need to add additional styles from a node_modules
plugin), we simply need to import css
, sass
or scss
files in the src/styles.ts
file. This file is included in your bundle because it is referenced inside root index.html
file
// file: ./src/styles.ts
// ...
import "notyf/notyf.min.css";
import "./scss/main.scss";
// ...
All imported files here are to be converted in
css
, and injected automatically inindex.html
at build and run time. The injected styles are available globally.
Bulma Integration
Classic Bulma used to be fully integrated with Vuero. This meant that when you changed the $primary
Vuero color variable, it took precedence over any Bulma related variable. In Vuero 2.0.0
, things have heavily changed like we discussed above. Vuero is now fully supporting native CSS variables and dropped Sass varibales support.
Native Dark Mode
Vuero comes with a native Dark mode. This means that all components are prestyled for dark mode. You don't have to worry about it, when you turn it on, the colors change seamlessly. Dark mode styling is made through a global .is-dark
class added to the page <html>
root element. Dark mode is toggled on the body with javascript. In another type of implementation, the body would have to be rendered by the server with the proper class before being served to the client, based on the user selection.
TIP
.is-dark
class is not restricted to <html>
element, you can add this class to any element, so all childrens will be in dark mode!
Dark Mode and CSS vars
In previous Vuero versions, the dark mode implementation required to have additional nested styles inside a .is-dark
class modifier. With the introduction of CSS vars, Dark Mode is now handled at the color level. You can control how a CSS variable behaves at runtime, based on the parent classes. For example let's says we have a CSS variable like this: --color: red
. We can change the value of this color in dark mode by editing the variable, preventing us to write additional dark mode CSS code.
// Normal mode
:root {
--color: red;
}
// Dark mode
.is-dark {
--color: blue;
}
Lazyloading Scss
my-vuero-quickstarter-project/
├── src/
│ ├── components/
│ │ └── pages/
The pages folder holds the template pages as chunks of reusable UI that can be inserted in all available layout types. Each page is a Vue 3 component with a <style>
element that holds required SCSS for that page. This way, you do not load unecessary CSS when browsing.
They are not added by default to main.scss
, instead we lazyload them in layouts or directly in pages:
<!-- file ./src/pages/status.vue -->
<script setup lang="ts">
// ...
</script>
<template>
<!-- ... -->
</template>
<style lang="scss">
/* files imported in components will be loaded only once they are needed */
@import "../scss/abstracts/_mixins.scss";
@import "../scss/pages/generic/_utility.scss";
.status-page-wrapper {
/* custom scss for this page */
&:hover {
color: var(--primary);
}
}
</style>
Scoped SCSS in Vue Components
Vue 3 being very powerful, we built Vuero so you don't have to worry about moving components from a folder to another or from a project to another. It is as simple as copying and pasting your components in the target folder. Because this project uses the unplugin-vite-components
, all your components are parsed and available in your pages and other components without a single import statement. We kept the components CSS out of the .vue
files so it is easier for you to explore the template styles and to adapt them to your needs.
However, we recommend that when you build your own project with Vuero, you take advantage of the .vue
files potential by scoping your styles to your component, like we do with the page components. This way, the component styles are only loaded when the component is displayed.
<script setup lang="ts">
export type MyComponentColors = 'red' | 'blue' | 'green'
export interface MyComponentsProps = {
color?: MyComponentColors
label: string
}
const props = defineProps<MyComponentsProps>();
</script>
<template>
<button class="button" :class="[props.color && `is-${props.color}`]">
{{ props.label }}
</button>
</template>
<style lang="scss" scoped>
.button {
&.is-red {
color: var(--red);
}
&.is-blue {
color: var(--blue);
}
&.is-green {
color: var(--green);
}
&.is-purple {
color: var(--purple);
}
}
</style>