DEV Community

Cover image for Oruga - UI components library without CSS framework dependency
Walter Tommasi
Walter Tommasi

Posted on

Oruga - UI components library without CSS framework dependency

During my work on Buefy (thanks to all community ๐Ÿ˜‰) I realized that to be bounded to a CSS Framework might be limiting for a UI components library that it isn't only a simple wrapper. Then I tried to use the current codebase in some way to be CSS frameworkless and so was born the idea called Oruga ๐ŸŽ‰

Oruga is a lightweight library of UI components for Vue.js without CSS framework dependency.

Oruga UI is like a caterpillar, minimal and yet functional. It's in your hands turning it into a butterfly (๐Ÿ›) => ๐Ÿฆ‹

Nice, but what does it mean? ๐Ÿ˜ฎ

The main idea behind Oruga is to be a UI components library CSS framework agnostic. It doesn't depend on Bootstrap, Bulma, Material, TailwindCSS, etc but it offers an easy way to integrate with one of them.

All components are individually importable (tree shaking) and they aren't a simple wrapper of native elements but they add new and custom features.

Oruga allows to customize a component in 4 different ways:

  • using CSS variables
  • using SASS/SCSS variables
  • adding new classes on the base theme or oruga-lite theme
  • overriding all classes

but you can mix them, for example adding new classes and using CSS variables!

In the following examples, I'll show you how to customize the component o-dropdown in 3 different ways without losing any functional features of the component itself.

CSS Variables

It is a very simple way to customize the default style of a component by CSS stylesheet or dynamically by Javascript.

:root {
  --oruga-dropdown-menu-width: 300px;
  --oruga-dropdown-menu-box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1),
    0 0 0 1px rgba(10, 10, 10, 0.02);

All dropdown variables are listed here.

SASS/SCSS Variables

It allows making static themes choosing the default values of style attributes for each component and to customize the final CSS bundle with all Oruga features (css-vars, css-vars prefix name, whitelist, etc.)

The base config is available here

Adding new classes (+ oruga-lite)

Oruga offers a minimal style that tries to cover the style of a single component but sometimes might be not easy add/override a default style; for this reason, you can import oruga-lite.css, a lite stylesheet that doesn't contain any styles attributes (background, color, padding, width, etc).

The example shows the integration between Oruga and TailwindCSS.

Note: the example uses TailwindCSS because of its popularity but it works with custom classes (own company design system) or other CSS frameworks/libraries.
Note 2: All single classes (bg-blue, text-white, ...) could be wrapped into a one custom class for each component prop, it was only an example choice

import Oruga from "@oruga-ui/oruga";
import "@oruga-ui/oruga/dist/oruga-lite.css";

Vue.use(Oruga, {
  // ...
  dropdown: {
    menuClass: "m-0 bg-white shadow-lg min-w-0  rounded-sm",
    backgroundClass: "bg-gray-900 bg-opacity-75",
    itemClass: "px-2 py-2",
    itemActiveClass: "bg-blue-500 text-white"
  // ...

As you can see the mobile feature (dropdown content (items) are shown into a modal on mobile) is always available and it follows the custom style added.

In alternative, you can add a custom style to a single component instance, for example:

<o-dropdown menu-class="m-0 bg-white shadow-lg min-w-0  rounded-sm" ...> ...
  <o-dropdown-item item-class="px-2 py-2">...</o-dropdown-item>


In this case, you have full power and you can customize all parts of the component (of course it's about what Oruga allows ๐Ÿ˜ƒ)

Setting the field override to true, the component won't use any default classes but it will apply all custom classes defined as below:

import Oruga from "@oruga-ui/oruga";

Vue.use(Oruga, {
  // ...
  dropdown: {
    override: true,
    rootClass: "inline-flex relative",
      "tail-dropdown-menu m-0 bg-white shadow-lg min-w-0 rounded-sm",
    backgroundClass: "tail-dropdown-background",
    itemClass: "relative block no-underline cursor-pointer px-2 py-2",
    itemActiveClass: "bg-blue-500 text-white",
    mobileClass: "tail-dropdown-mobile"
  // ...

Here we have the same result as above but looking in the code the added classes are not about styles (background, color) but they must provide the structural style attributes (position, display, etc).
For example, I had to add tail-dropdown-menu to menu-class field in order to show the dropdown menu in the correct position of the window and relative to the trigger button.

.tail-dropdown-menu {
  top: 100%;
  min-width: 12em;
  position: absolute;
  left: 0;

It's better to evaluate to use oruga-lite stylesheet before in order to really take care only of pure style part; anyway, all depend on project/ui needs.

If youโ€™re interested and you don't want to write new components (simple and complex) from scratch it could be a good idea give a try to Oruga ๐Ÿ˜‰

Top comments (2)

momander profile image
Martin Omander

I think Oruga is exciting and will find an audience. But I will probably stick with Buefy. Why?

I am a programmer who understands Javascript better than CSS. I picked Buefy because it gave my web app a good look with little effort required. That lets me focus on building new features for my users, responding to user emails, fixing bugs, etc. If I had unlimited time, I would learn more CSS and pick up Oruga.

Best of luck with the new project, and please don't forget your Buefy audience! We really appreciate your hard work!

wesdevpro profile image
Wesley Ford

I agree. However I would say there is room for frameworks that support an easy work load, and there is room for frameworks, like Oruga, that support total customization. However, I hope Buefy does get a bump up to Vue3, and nuxt3, a lot of my projects use it and the convenience of Buefy can not be beat. I would like to propose though a compromise. Buefy could potentially work on top of Oruga. This would lighten the load on maintaining both projects. However, this could increase the over head and bundle size.