classnames
    Overview
    Dependencies
    Versions
    Playground
    Code
    Documentation
    Issues
    Find an Expert
    Career Opportunities
    Alternatives
    Insights & Analysis

classnames

A simple utility for conditionally joining classNames together

2.2.6  •  Published 1 years ago  •  by Jed Watson  •  MIT License

Classnames

Version Build Status Supported by Thinkmill

A simple JavaScript utility for conditionally joining classNames together.

Install with npm, Bower, or Yarn:

npm:

npm install classnames --save

Bower:

bower install classnames --save

Yarn (note that yarn add automatically saves the package to the dependencies in package.json):

yarn add classnames

Use with Node.js, Browserify, or webpack:

var classNames = require('classnames');
classNames('foo', 'bar'); // => 'foo bar'

Alternatively, you can simply include index.js on your page with a standalone <script> tag and it will export a global classNames method, or define the module if you are using RequireJS.

Project philosophy

We take the stability and performance of this package seriously, because it is run millions of times a day in browsers all around the world. Updates are thoroughly reviewed for performance impacts before being released, and we have a comprehensive test suite.

Classnames follows the SemVer standard for versioning.

There is also a Changelog.

Usage

The classNames function takes any number of arguments which can be a string or object. The argument 'foo' is short for { foo: true }. If the value associated with a given key is falsy, that key won’t be included in the output.

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

Arrays will be recursively flattened as per the rules above:

var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

Dynamic class names with ES2015

If you’re in an environment that supports computed keys (available in ES2015 and Babel) you can use dynamic class names:

let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true });

Usage with React.js

This package is the official replacement for classSet, which was originally shipped in the React.js Addons bundle.

One of its primary use cases is to make dynamic and conditional className props simpler to work with (especially more so than conditional string manipulation). So where you may have the following code to generate a className prop for a <button> in React:

var Button = React.createClass({
  // ...
  render () {
    var btnClass = 'btn';
    if (this.state.isPressed) btnClass += ' btn-pressed';
    else if (this.state.isHovered) btnClass += ' btn-over';
    return <button className={btnClass}>{this.props.label}</button>;
  }
});

You can express the conditional classes more simply as an object:

var classNames = require('classnames');

var Button = React.createClass({
  // ...
  render () {
    var btnClass = classNames({
      btn: true,
      'btn-pressed': this.state.isPressed,
      'btn-over': !this.state.isPressed && this.state.isHovered
    });
    return <button className={btnClass}>{this.props.label}</button>;
  }
});

Because you can mix together object, array and string arguments, supporting optional className props is also simpler as only truthy arguments get included in the result:

var btnClass = classNames('btn', this.props.className, {
  'btn-pressed': this.state.isPressed,
  'btn-over': !this.state.isPressed && this.state.isHovered
});

Alternate dedupe version

There is an alternate version of classNames available which correctly dedupes classes and ensures that falsy classes specified in later arguments are excluded from the result set.

This version is slower (about 5x) so it is offered as an opt-in.

To use the dedupe version with Node.js, Browserify, or webpack:

var classNames = require('classnames/dedupe');

classNames('foo', 'foo', 'bar'); // => 'foo bar'
classNames('foo', { foo: false, bar: true }); // => 'bar'

For standalone (global / AMD) use, include dedupe.js in a <script> tag on your page.

Alternate bind version (for css-modules)

If you are using css-modules, or a similar approach to abstract class “names” and the real className values that are actually output to the DOM, you may want to use the bind variant.

Note that in ES2015 environments, it may be better to use the “dynamic class names” approach documented above.

var classNames = require('classnames/bind');

var styles = {
  foo: 'abc',
  bar: 'def',
  baz: 'xyz'
};

var cx = classNames.bind(styles);

var className = cx('foo', ['bar'], { baz: true }); // => "abc def xyz"

Real-world example:

/* components/submit-button.js */
import { Component } from 'react';
import classNames from 'classnames/bind';
import styles from './submit-button.css';

let cx = classNames.bind(styles);

export default class SubmitButton extends Component {
  render () {
    let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';
    let className = cx({
      base: true,
      inProgress: this.props.store.submissionInProgress,
      error: this.props.store.errorOccurred,
      disabled: this.props.form.valid,
    });
    return <button className={className}>{text}</button>;
  }
};

Polyfills needed to support older browsers

classNames >=2.0.0

Array.isArray: see MDN for details about unsupported older browsers (e.g. <= IE8) and a simple polyfill.

Object.keys: see MDN for details about unsupported older browsers (e.g. <= IE8) and a simple polyfill. This is only used in dedupe.js.

License

MIT. Copyright © 2017 Jed Watson.

Dependencies

benchmark  ·  browserify  ·  mocha  ·  opn-cli

Tags

react
css
classes
classname
classnames
util
utility
Keep your dependencies fresh!
Upgrade your packages safely and continuously.
We run your CI tests and compatability tests on new versions of your packages - to determine which upgrades are safe
Just $9/month per developer

Popularity

Weekly Downloads
3.2M
Stars
11.0K

Issues and PRs

Activity

Last ver 1 year ago
Created 5 years ago
Last commit 2 months ago
7 days between commits

Sustainability

41 contributors

Technology

Node version: 8.4.0
16.3K unpacked

Legal and Compliance

MIT License
OSI Approved
0 vulnerabilities

Top Experts

Jed Watson
Maintainer, 123 commits, 34 merges, 1 PRs
Works at Thinkmill
Daniel Cousens
Maintainer, 49 commits, 17 merges, 5 PRs
Ross Allen
11 commits
Bart Riordan
7 commits, 1 PRs
Cheng Lou
4 commits, 4 PRs
Works at Facebook
Kirill Yakovenko
4 commits, 1 PRs