# Introduction
Oruga is a lightweight library of UI components for Vue.js without CSS framework dependency.
It doesn't depend on any specific style or CSS framework (like Bootstrap, Bulma, TailwindCSS, etc) and it doesn't provide any grid system or CSS utility, it just offer a set of components easy to customize only modifying your stylesheets or integrating it with a CSS framework (see the demo).
Oruga wants you to focus only on UI/UX aspects of your application and be totally flexible to future changes without having to touch a line of JavaScript.
If you need a component library and want to easily apply your custom styles, Oruga is the library for you! 🐛
# Oruga default stylesheet
Oruga comes with a default stylesheet containing only the essential rules for Oruga components such as display, position, z-index and other basic attributes. You can use the default Oruga stylesheet in this documentation turning on the switch in the navbar.
If you use the default stylesheet to browse documentation some examples won't work as you expect because sizes, variants and adornments are not included in the Oruga default stylesheet. For more info read "Differences between default and full css" or go to "Customization section" if you want to know more about components customization.
# Availability
🐛 Oruga is available for Vue.js version 2.6+ or version 3.x and has been tested in all major browsers
Latest ✔ | Latest ✔ | 10+ ✔ | Latest ✔ | 6.1+ ✔ | IE 11 ✔ |
💅 For more info about components customization, go to the "Customization section".
🕹 To see Oruga in action, go to the "Examples" section.
# Setup
# Vue 2
# Build from "develop" branch
<link rel="stylesheet" href="https://preview.oruga.io/cdn/oruga.min.css" />
<script src="https://preview.oruga.io/cdn/oruga.min.js"></script>
# Full bundle
import Vue from 'vue'
import Oruga from '@oruga-ui/oruga'
import '@oruga-ui/oruga/dist/oruga.css'
Vue.use(Oruga)
# Individual components (tree shaking)
import Vue from 'vue'
import { OAutocomplete, OSidebar } from '@oruga-ui/oruga'
import '@oruga-ui/oruga/dist/oruga.css'
Vue.component(OAutocomplete)
Vue.component(OSidebar)
# Vue 3
# Full bundle
import { createApp } from 'vue'
import Oruga from '@oruga-ui/oruga-next'
import '@oruga-ui/oruga-next/dist/oruga.css'
createApp(...).use(Oruga);
# Individual components (tree shaking)
import { createApp } from 'vue'
import { OAutocomplete, OSidebar } from '@oruga-ui/oruga-next'
import '@oruga-ui/oruga-next/dist/oruga.css'
createApp(...)
.use(OAutocomplete)
.use(OSidebar)
# Nuxt module
Oruga provides a Nuxt.js module to easily integrate the library in your Nuxt.js app.
Add @oruga-ui/oruga/nuxt
to modules
section of your nuxt.config.js
file.
module.exports = {
modules: ['@oruga-ui/oruga/nuxt']
}
You can also extend and/or override classes in this section (see how to add new classes or override existing classes in Oruga)
module.exports = {
modules: [
[
'@oruga-ui/oruga/nuxt',
{
button: {
override: true
}
}
]
]
}
By default Oruga Nuxt module includes oruga.css
stylesheet. If you want to avoid including it you can set includeCss
to false
inside nuxt.conf.js
oruga: {
includeCss: false
},
includeCss
accepts other 2 values:
full
to includeoruga-full.css
vars
to includeoruga-full-vars.css
See "Customization section" to understand the difference between these stylesheets.
Alternatively you can use Nuxt.js plugins system adding a file (e.g. oruga.js
) in your plugins
folder containing
import Vue from 'vue'
import Oruga from '@oruga-ui/oruga'
import '@oruga-ui/oruga/dist/oruga.css'
Vue.use(Oruga)
To make this plugin available in your app, add this file to the plugins
array in your nuxt.config.js
plugins: [{ src: '~plugins/oruga.js' }]
To understand how the plugins work with Nuxt.js, take a look at the NuxtJS plugin documentation.
# Customization
Oruga allows you to customize components in 3 different ways:
You can mix them, for example adding new classes and using CSS variables!
Oruga provides oruga.css
, a lightweight stylesheet containing only minimal CSS rules (position, display, z-index ...). Include it if you want to perform a complete customization.
Oruga provides other 2 different stylesheets:
oruga-full.css
: a stylesheet containing the complete Oruga style (the default style used for documentation).oruga-full-vars.css
: a stylesheet containing the complete Oruga style with css vars you can redefine in your application. For more information click here.
For more info read "Differences between default and full css".
# Adding new classes or override existing ones
With Oruga you can easily override existing components style appending one or more classes. Each component has a Class prop
section (for example see Dropdown Class props) where you can inspect elements each class property affects using the Class prop inspector
.
# Adding classes
You can add classes to a component using class properties (see Autocomplete class props for example)
# Adding classes from props
<o-autocomplete root-class="myautocomplete-root" menu-class="myautocomplete-menu" item-class="myautocomplete-item" />
# Adding classes globally
import Vue from 'vue';
import Oruga from '@oruga-ui/oruga';
import '@oruga-ui/oruga/dist/oruga.css';
Vue.use(Oruga, {
autocomplete: {
rootClass: 'myautocomplete-root',
menuClass: 'myautocomplete-menu',
itemClass: 'myautocomplete-item',
...
}
});
If you use individual imports you can customize each component using Config
plugin.
import Vue from 'vue';
import { OAutocomplete, OSidebar, Config } from '@oruga-ui/oruga';
Vue.component(OAutocomplete);
Vue.component(OSidebar);
Vue.use(Config, {
autocomplete: {
rootClass: 'myautocomplete-root',
menuClass: 'myautocomplete-menu',
itemClass: 'myautocomplete-item',
...
}
})
You can also use an array
to specify more than one class or a function
to extend or override classes in a component. In case you use a function, a suffix is provided by the component and it can be used inside the function. For example, menuPositionClass
in Autocomplete provides a suffix to specify menu position (top, bottom), in this case you may define a function and append the suffix to the base class name
Vue.use(Config, {
autocomplete: {
rootClass: 'myautocomplete-root',
menuClass: 'myautocomplete-menu',
menuPositionClass: {
class: (suffix) => {
return `myautocomplete-menu-${suffix}`
}
},
itemClass: 'myautocomplete-item',
}
})
For a better customization experience this function accepts the component's context
containing its read-only attributes (props
, data
and computed
) as second parameter. For example using Bootstrap you may want to apply variants to buttons only when the element is not outlined
Vue.use(Config, {
input: {
rootClass: (_, context) => {
if (context.computed.hasIconRight) {
return 'has-icons-right')
}
},
variantClass: (variant, context) => {
if (!context.props.outlined) {
return `btn-${variant}`
}
}
},
...
}
# Deal with specificity
Oruga CSS comes with the lowest specifity possible, that's why you can easily override existing classes by defining new ones in the global configuration or using attributes. However there are some cases where specificty is higher than you expect, for example in the Steps component the nav item
contains a marker
and a divider
which colors change whether the nav item is active or not.
.o-steps {
...
&__nav-item-active {
.o-steps__link {
cursor: default;
}
.o-steps__marker {
@include avariable('background-color', 'steps-maker-default-color', $steps-maker-default-color);
@include avariable('border-color', 'steps-active-color', $steps-active-color);
@include avariable('color', 'steps-active-color', $steps-active-color);
}
.o-steps__divider {
background-position: left bottom;
}
}
&__nav-item-previous {
.o-steps__marker {
@include avariable('color', 'steps-maker-default-color', $steps-maker-default-color);
@include avariable('background-color', 'steps-previous-color', $steps-previous-color);
}
.o-steps__divider {
background-position: left bottom;
}
}
...
}
If you want to change the color you can use !important
or change variables values. Otherwise you can easily increase the specificity in your stylesheet
.steps-nav-item-active .step-marker {
color: blue;
border-color: blue;
}
.steps-nav-item-active .step-divider {
background-color: blue;
}
.steps-nav-item-previous .step-marker {
background-color: blue;
}
.steps-nav-item-previous .step-divider {
background-color: blue;
}
and then configure Oruga to use your custom classes
Vue.use(Oruga, {
steps: {
itemActiveClass: 'steps-nav-item-active',
itemPreviousClass: 'steps-nav-item-previous',
stepMarkerClass: 'step-marker',
stepDividerClass: 'step-divider',
}
});
You can see this code in action in Oruga multiframework example(code here)
Sometimes components change how elements are positioned (horizontally, vertically...), this is another case of higher specificity. In the Steps component the vertical
attribute disposes the steps vertically changing the height
of the steps divider
.
.o-steps {
&__wrapper-vertical {
display: flex;
flex-direction: row;
.o-steps__divider {
height: 100%;
@include avariable('width', 'steps-divider-height', $steps-divider-height);
top: -50%;
left: calc(50% - #{$steps-divider-height / 2});
}
...
}
...
}
If you want to set height to 50% keeping the other attributes unchanged you can't just define a new class (unless you want to use !important
), because of a higher specificity. In that case, we suggest to define your new class in this way
.steps-vertical .step-divider {
height: 50%;
}
and in your configuration
Vue.use(Oruga, {
steps: {
verticalClass: 'steps-vertical',
stepDividerClass: 'step-divider'
}
});
In Oruga documentation you'll find a special note (🔍) in the Class prop inspector
for classes with a higher specificity.
# Overriding classes
In case you want to override Oruga existing classes completely, you can act as above and set the field override
to true.
import Vue from 'vue';
import Oruga from '@oruga-ui/oruga';
Vue.use(Oruga, {
autocomplete: {
override: true,
rootClass: 'myautocomplete-root',
menuClass: 'myautocomplete-menu',
itemClass: 'myautocomplete-item',
...
}
});
or directly in your component
<o-autocomplete
override
rootClass="myautocomplete-root">
WARNING
In this case override
property replaces Oruga existing classes completely, ignoring your configuration.
You can also specify the override behaviour for each class
Vue.use(Config, {
autocomplete: {
rootClass: {
class: 'myautocomplete-root',
override: true
},
menuClass: 'myautocomplete-menu',
itemClass: 'myautocomplete-item',
...
}
})
# Transform classes
In case you want to transform applied classes' names you can use transformClasses
function directly in your configuration.
Vue.use(Config, {
button: {
transformClasses: (appliedClasses) => {
return appliedClasses.replace(/-/g, '--')
}
}
...
})
You can also use transformClasses
globally if you need to transform classes for any component.
Vue.use(Config, {
transformClasses: (appliedClasses) => {
return appliedClasses.replace(/-/g, '--')
}
...
})
# Using CSS or SASS/SCSS variables
You can easily customize Oruga using CSS or SASS/SCSS variables. Each component has its own variables, mostly of them with default values defined in the base style (see utilities/_variables.scss).
To use CSS variables you have to import oruga-full-vars.css
stylesheet
import '@oruga-ui/oruga/dist/oruga-full-vars.css'
and redefine the variables you want to change.
For example to change variants globally using CSS variables you can do
:root {
--oruga-variant-primary: green;
--oruga-variant-danger: red;
}
or a specific component variable, such as button icon width
:root {
--oruga-button-icon-width: 2.5em;
}
To use SASS/SCSS variables you have to use .scss files placed in the Oruga package
import '@oruga-ui/oruga/src/scss/oruga-full-vars';
WARNING
In order to work with SASS/SCSS you might also have to install sass
and sass-loader
depending on your environment.
An example can be found in the Button style section: here you'll find the complete list of all the CSS and SASS/SCSS variables (with their respective default values) you can redefine for each component.
# Configuration
Oruga allows to customize each components using config constructor or programmatically using this.$oruga.config
.
{
globalfield: string|boolean|number|function|....,
componentname: {
override: boolean,
customfieldX: string|boolean|number|function|....
}
}
For example:
{
button: {
override: true,
rootClass: 'btn',
roundedClass: 'btn-rounded',
...
}
}
# Differences between default and full css
The default stylesheet contains only the essantial rules for Oruga components such as display, position, z-index and other basic attributes.
For example to style a dropdown using override mode with oruga default stylesheet using TailwindCSS
import '@oruga-ui/oruga/dist/oruga.css'
.dropdown {
@apply inline-flex relative;
}
.dropdown-menu {
top: 100%;
min-width: 12em;
@apply absolute bg-white left-0 m-0 px-2 shadow-lg rounded-sm z-10;
}
.dropdown-item {
@apply relative block no-underline px-1 py-2 cursor-pointer;
}
And here's how to style a dropdown using oruga-full stylesheet
import '@oruga-ui/oruga/dist/oruga-full.css'
.dropdown-menu {
min-width: 12em;
@apply bg-white m-0 px-2 shadow-lg rounded-sm z-10;
}
.dropdown-item {
@apply no-underline px-1 py-2 cursor-pointer;
}
Take a look at the official TailwindCSS + Oruga example.
# Global Props
Field | Description | Default |
---|---|---|
statusIcon | Show status icon using field and variant prop | true |
statusVariantIcon | Default mapping of variant and icon name | { |
useHtml5Validation | Default form components use-html5-validation attribute | true |
iconPack | Icon pack used internally and on the Icon component attribute | 'mdi' |
reportInvalidInput | Callback function that allows for custom behavior when HTML constraint validation would visually report that a field is invalid. Takes the input and its parent field (if any) as arguments. | null |
Take a look at each component docs to know all customizable fields/props by config.
# Base Style
SASS Variable | Default |
---|---|
$base-border-radius | 4px |
$base-font-size | 1rem |
$base-rounded-border-radius | 9999px |
$base-line-height | 1.5 |
$base-disabled-opacity | 0.5 |
$speed | 300ms |
$speed-slow | 150ms |
$speed-slower | 250ms |
$easing | ease-out |
$control-border-width | 1px |
$control-height | 2.25em |
$white | #ffffff |
$black | #000000 |
$grey | #7a7a7a |
$grey-light | #b5b5b5 |
$grey-lighter | #dbdbdb |
$primary | #445e00 |
$primary-invert | $white |
$danger | #b60000 |
$danger-invert | $white |
$warning | #f4c300 |
$warning-invert | $black |
$success | #006724 |
$success-invert | $white |
$info | #005C98 |
$info-invert | $white |
$whitelist | () |
$sass-vars | true |
$css-vars | true |
$variable-prefix | '--oruga-' |
$sizes | ( "small": .75rem, "medium": 1.25rem, "large": 1.5rem ) |
$colors | ( "primary": ($primary, $primary-invert), "danger": ($danger, $danger-invert), "warning": ($warning, $warning-invert), "success": ($success, $success-invert), "info": ($info, $info-invert) ) |
# Examples
# TailwindCSS, Bootstrap 5, Bulma and Material demo 🧶
# TailwindCSS 2 Recipe Demo 🍝🍔🍟
This simple demo shows a simple recipe website. Oruga components like Input, Radio, Loading, Switch, Collapse etc are customized using TailwindCSS 2!