/bulma-classnames

Simple utility for creating Bulma.css classnames using JavaScript objects

Primary LanguageJavaScriptMIT LicenseMIT

bulma-classnames

Simple utility for creating declarative classnames in JSX for bulma.css using JavaScript objects

npm Travis (.org) Coveralls github branch GitHub last commit GitHub issues npm bundle size (minified + gzip) GitHub PRs Welcome semantic-release Commitizen friendly

The problem

Writing long classnames for the Bulma.css stylesheet inline makes your code ugly and is hard to read at a glance, for example:

<h1 className="has-text-primary is-size-1-desktop is-size-2-tablet is-size-3-touch is-size-4-mobile has-text-left-mobile has-text-centered-desktop">Hello, world!</h1>

This problem gets even worse when you start to nest components and have a giant mess of spaghetti, for example:

<h1 className="has-text-primary is-size-1-desktop is-size-2-tablet is-size-3-touch is-size-4-mobile has-text-left-mobile has-text-centered-desktop">
  Hello,
  <a href="/world" className="has-text-secondary is-capitalized has-text-weight-bold">
    world!
  </a>
</h1>

Ugh!

This solution

The bulma-classnames utility package helps you write these classnames using a simple javascript object in a more readable way. Here's the example from above rewritten in JSX and bulma-classnames:

let styles = bulma({
  textColor: 'primary',
  textSize: ['1-desktop', '2-tablet', '3-touch', '4-mobile'],
  textAlign: ['left-mobile', 'centered-desktop']
});

<h1 className={styles}>
  Hello, world!
</h1>

And rewritten again inline if you prefer to do things that way:

<h1 className={
  bulma({
    textColor: 'primary',
    textSize: ['1-desktop', '2-tablet', '3-touch', '4-mobile'],
    textAlign: ['left-mobile', 'centered-desktop']
  })
}>
  Hello, world!
</h1>

So much better, right?!

What this package is not:

  • A stylesheet. This package will only take in a declarative JavaScript object and return a formatted string for you to use as a classname in your code. You'll still need to install the Bulma.css stylesheet.
  • Something that you'll use in a <script> tag in the browser. This package is designed to be used in a JSX environment, such as React.js, Preact.js or Inferno.

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:

npm install bulma-classnames

Or via the yarn package manager:

yarn add bulma-classnames

Usage

Simply import bulma into your file and use the function anywhere that you need to create a bulma classname string. The bulma function accepts a JavaScript object with as many of the accepted key:value pairs shown in the API and returns a single, formatted string with all of the classnames.

import bulma from 'bulma-classnames'

// this will create the following string
// 'has-text-primary has-text-left is-size-1-mobile is-size-2-tablet is-size-3-mobile'
let styles = bulma({
  textColor: 'primary',
  textAlign: 'left',
  textSize: ['1-desktop', '2-tablet', '3-mobile']
});

let MyComponent = (
  <h1 className={styles}>
    Hello, world!
  </h1>
)

/*
*
* And this is what will be rendered
* let MyComponent = (
*   <h1 className="has-text-primary has-text-left is-size-1-mobile is-size-2-tablet is-size-3-mobile">
*     Hello, world!
*   </h1>
* )
*
*/

You can also use the function inline if you prefer:

import bulma from 'bulma-classnames'

let MyComponent = (
  <h1 className={
    bulma({
      textColor: 'primary',
      textAlign: 'left',
      textSize: ['1-desktop', '2-tablet', '3-mobile']
    })
  }>
    Hello, world!
  </h1>
)

/*
*
* And this is what will be rendered
* let MyComponent = (
*   <h1 className="has-text-primary has-text-left is-size-1-mobile is-size-2-tablet is-size-3-mobile">
*     Hello, world!
*   </h1>
* )
*
*/

Single values

You can pass either a single string value:

let styles = bulma({
  textColor: 'primary',
  textAlign: 'left'
})

// 'has-text-primary has-text-left'

Multiple values

Or an array of values, which is extremely helpful for repetetive helpers with different values, like 'mobile,' 'tablet,' 'desktop,' etc. bulma will format each array value with the correct prefix and combine them all into the same classname string.

let styles = bulma({
  textSize: ['1-desktop', '2-tablet'],
  textAlign: ['left-mobile', 'right-tablet', 'centered-desktop']
})

// 'is-size-1-desktop is-size-2-tablet has-text-left-mobile has-text-right-tablet has-text-centered-desktop'

And here's how you can change the name of the function during your import for a shorter syntax:

import bulma as bc from 'bulma-classnames'

let MyComponent = (
  <h1 className={
    bc({
      textColor: 'primary',
      textAlign: 'left',
      textSize: ['1-desktop', '2-tablet', '3-mobile']
    })
  }>
    Hello, world!
  </h1>
)

/*
*
* And this is what will be rendered
* let MyComponent = (
*   <h1 className="has-text-primary has-text-left is-size-1-mobile is-size-2-tablet is-size-3-mobile">
*     Hello, world!
*   </h1>
* )
*
*/

Is, has, and raw

Although it's preferred to use the most specific key instad of is or has, you can always use these helpers as an escape hatch or for simple helpers like is-marginless.

let styles = bulma({
  is: ['marginless'],
  textAlign: ['addons', 'addons-right']
})

// 'is-marginless has-addons has-addons-right'

And here's an example of a bad way to use the is and has helper, since it's harder to read at a glance and is less declarative:

let styles = bulma({
  is: 'capitalized',
  has: ['text-right-mobile', 'text-left-desktop']
})

// 'is-capitalized has-text-right-mobile has-text-left-desktop'

And the better way to accomplish the same example above, but more declaratively:

let styles = bulma({
  textTransform: 'capitalized',
  textAlign: ['right-mobile', 'left-desktop']
})

// 'is-capitalized has-text-right-mobile has-text-left-desktop'

Raw

raw is a simple way to add extra classnames without formatting them. Any string that you add in raw will be added to the end of the classname string.

let styles = bulma({
  color: 'primary',
  raw: 'extra-classname another-classname'
})

// 'is-primary extra-classname another-classname'

API

Here's a list of all the accepted keys and their types.

backgroundColor

string - adds "is-background-" to the front of the string

bulma({
  backgroundColor: 'primary'
})

// => 'is-background-primary'

color

string - adds "is-" to the front of the string

bulma({
  color: 'primary'
})

// => 'is-primary

column

string | string[] - adds "is-" to the front of each string and "column" to the end

bulma({
  column: '10-mobile'
})

// => 'is-10-mobile column'

bulma({
  column: [ '10-mobile', '11-desktop', '12-widescreen']
})
// => 'is-10-mobile is-11-desktop is-12-widescreen column'

offset

string | string[] - adds "is-offset-" to the front of each string

bulma({
  offset: '10-mobile'
})

// => 'is-offset-10-mobile'

bulma({
  offset: [ '10-mobile', '11-desktop', '12-widescreen']
})

// => 'is-offset-10-mobile is-offset-11-desktop is-offset-12-widescreen'

flex

string | string[] - adds "is-flex" to the front of each string

bulma({
  flex: 'mobile'
})

// => 'is-flex-mobile'

bulma({
  flex: [ 'mobile', 'desktop', 'widescreen']
})

// => 'is-flex-mobile is-flex-desktop is-flex-widescreen'

inlineFlex

string | string[] - adds "is-inline-flex" to the front of each string

bulma({
  inlineFlex: 'mobile'
})

// => 'is-inline-flex-mobile'

bulma({
  inlineFlex: [ 'mobile', 'desktop', 'widescreen']
})

// => 'is-inline-flex-mobile is-inline-flex-desktop is-inline-flex-widescreen'

block

string | string[] - adds "is-block" to the front of each string

bulma({
  block: 'mobile'
})

// => 'is-block-mobile'

bulma({
  block: [ 'mobile', 'desktop', 'widescreen']
})

// => 'is-block-mobile is-block-desktop is-block-widescreen'

inlineBlock

string | string[] - adds "is-inline-block" to the front of each string

bulma({
  inlineBlock: 'mobile'
})

// => 'is-inline-block-mobile'

bulma({
    inlineBlock: [ 'mobile', 'desktop', 'widescreen']
})

// => 'is-inline-block-mobile is-inline-block-desktop is-inline-block-widescreen'

inline

string | string[] - adds "is-inline" to the front of each string

bulma({
  inline: 'mobile'
})

// => 'is-inline-mobile'

bulma({
  inline: [ 'mobile', 'desktop', 'widescreen']
})

// => 'is-inline-mobile is-inline-desktop is-inline-widescreen'

textColor

string - adds "has-text-color" to the front of the string

bulma({
  textColor: 'primary'
})

// => 'has-text-color-primary

textSize

string | string[] - adds "is-size-" to the front of the string

bulma({
  textSize: '6'
})

// => 'is-size-6'

bulma({
  textSize: ['5-mobile', '6-desktop', '7-widescreen']
})

// => 'is-size-5-mobile is-size-6-desktop is-size-7-widescreen'

textWeight

string - adds "has-text-weight" to the front of the string

bulma({
  textWeight: 'bold'
})

// => 'has-text-weight-bold'

textTransformation

string | string[] - adds "is-" to the front of the string

bulma({
  textTransformation: 'capitalized'
})

// => 'is-capitalized'

bulma({
  textTransformation: ['capitalized', 'italic']
})

// => 'is-capitalized is-italic'

textAlign

` string | string[]``` - adds "has-text-" to the front of the string

bulma({
  textAlign: 'left'
})

// => 'has-text-left'

bulma({
  textAlign: ['left-mobile', 'right-desktop', 'center-widescreen']
})

// => 'has-text-left-mobile has-text-right-desktop has-text-center-widescreen'

is

string | string[] - adds "is-" to the front of each string. Designed as an escape hatch, or for misc. helpers like is-marginless

bulma({
  is: 'marginless'
})

// => 'is-marginless'

bulma({
  is: ['marginless', 'pulled-left']
})

// => 'is-marginless is-pulled-left'

has

string | string[] - adds "has-" to the front of each string. Designed as an escape hatch, or for misc. helpers like has-addons

bulma({
  has: 'addons'
})

// => 'has-text-weight-bold'

bulma({
  has: ['addons', 'addons-right']
})

// => 'has-addons has-addons-right'

raw

string - outputs the exact same string that is passed, no formatting is added. Useful to pass extra classnames that either don't start with is or has o aren't related to Bulma in the same object

bulma({
  raw: 'column'
})

// => 'column'

Learning Material

Feel free to contribute more!

FAQ

Are there Flow and TypeScript types available?

Not yet, but I'm working on them and expect to have them finished soon. You can see my progress and contribute if you like!

What is Bulma.css?

Bulma.css is a beautiful stylesheet with helpers and components already pre-designed for you, like Bootstrap or Foundation. It uses classnames to reference the styles and is great for developers new to styling websites, or anyone that wants to use a battle-tested stylesheet to get going fast on a project. I used it heavily in my other project Sushi Commerce and it drove me to create this package to save hours of time and make my code much prettier to look at and reason about.

What if I hate CSS-in-JS?

Then this might still be great for you, because you're still doing the same thing as standard CSS - add classnames to an HTML object. But you're doing it more declaratively and modern. t still might feel weird putting your styles in an object at first though, and that's ok.

Guiding Principles

Long classname strings suck to write and suck to look at - JavaScript objects are much easier.

I think it's much more fun to write a declarative object in a small function to write my styles, while using the amazing Bulma.css stylesheet.

This package is a single function that formats the object with a class that has several switch statements and reducer functions.

Roadmap

  • Flow and TypeScript typings

Contributors

Sean W. Lawrence

Issues

Looking to contribute? Check out our roadmap and raise an issue on what you'd like to help with!

Bugs

Please raise an issue for bugs, missing documentation, or unexpected behavior.

Feature Requests

Please raise an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.

Questions

Please raise an issue if you have any questions about how to use this package.

Contributing

Contributions are welcome! If you'd like to help out, check the issues or create a new issue and let us know what you plan to work on. When you're ready to start, visit out instructions on how to contribute for more information.

Changelog

View the changelog to see all updates, which will be automatically updated by commitizen and semantic-release.

LICENSE

MIT

Made for bulma logo