Css modules multiple classes

CSS Modules with Multiple Classes

I’ve been struggling to think of topics to write about on my blog, and today had an ah-hah moment*. I can write about the technology I use at work and especially the problems I run into and how to solve them. That way I have nearly endless material to write about!

note: an ah-hah moment is when you finally discover the answer to a problem and you say “ah hah!”, also known as a eureka moment.

This week I have been working to implement CSS Modules in my React app at work. I wanted a more declarative approach to CSS that also had the benefit of not loading CSS that I am not using. CSS Modules allow you to access CSS via object dot notation and scope the CSS locally by default. Here is an example of CSS Modules:

Example.less

.container  max-width: 1200px; width: 100%; margin: auto; > .cards  display: flex; justify-content: space-around; > .card  width: 25%; > .card__title  font-weight: bold; > .card__body  text-align: center; > 

Example.js

// pretend there's a React component up here return ( div className=styles.container>> div className=styles.cards>> div className=styles.card>> h1 className=styles.card__title>>Lorem Ipsum/h1> p className=styles.card__body>>Lorem ipsum doler sit amet/p> /div> /div> /div> ) 

This renders as something like:

Example.html

div class="_styles__container_30103242"> div class="_styles__cards_30103242"> div class="_styles__card_30103242"> h1 class="_styles__card__title_30103242">Lorem Ipsumh1> p class="_styles__card__body_30103242">Lorem ipsum doler sit ametp> div> div> div> 

Example.css

._styles__container_30103242 . > ._styles__cards_30103242 . > ._styles__card_30103242 . > ._styles__card__title_30103242 . > ._styles__card__body_30103242 . > 

The CSS is now scoped only to the component and is much easier to work with. Never again should you run into unforeseen changes due to global CSS!

Hyphens and Multiple Class Names

One of the first problems I ran into immediately was writing elements with multiple class names. Say I have a button component with the classes of btn btn-info disabled . This wouldn’t work:

return ( button className=styles.btn styles.btn-info styles.disabled>> props.btnText> /button> ) 

I would get an error because className expects a single string, or something that renders into a string. This is where the classnames utility comes in handy. It allows us to write classnames programmatically without a lot of overhead.

npm install classnames —save

Now we can solve the problem of multiple classnames. We can also solve the problem of using hyphens with bracket notation. Instead of style.btn-info we would write style[‘btn-info] . It can be clunky to write a lot of code that way, but there are other alternatives available. Here is a button component example similar to what I would use at work including CSS modules, multiple classnames, and hyphenated classnames:

Button.less

.btn . > .btn-info . > .btn-default . > .btn-warning . > .btn-danger . > 

Button.js

import React from 'react' import PropTypes from 'prop-types' import cx from 'classnames' import styles from './Button.less' const Button = (props) =>  return ( button className=cx( // first class styles.btn, // second class with hyphen styles[`btn-$props.type>`], // third class with conditional rendering. If props.disabled is // false, it will not add the class to the component  [styles.disabled]: props.disabled > )> onClick=(e) =>  props.onClick(e) >>> props.btnText> /button> ) > Button.propTypes =  type: PropTypes.oneOf([ 'info', 'default', 'warning', 'danger' ]).isRequired, disabled: PropTypes.bool, btnText: PropTypes.string.isRequired, onClick: PropTypes.func.isRequired > 

I hope this helped you get a feel for using multiple classes with CSS modules. There are probably better ways to accomplish this and I hope to learn them soon. If you have any tips for how to improve this approach or any other critique or feedback, feel free to leave a comment below or @ me on Twitter. Thanks for reading!

Written by Josiah Rooney, a self-taught software engineer from Northern California. You should follow him on Twitter

Источник

Using Multiple Classes With React CSS Modules

When working with CSS modules in React, applying styles from one class is straightforward. But, what about using multiple or nested class selectors? In this post, I will show you how to use multiple classes on one element using CSS modules in React. I will also teach you what to do when you have nested class selectors. If you are using Sass/SCSS modules, I have it covered at the end of the post as well.

Working with Many Classes in CSS Modules

Let’s start by applying styling from a single class in CSS modules. Create a CSS module file — Button.module.css .

.button   background-color: #ffffff;  border: 1px solid #2779e4;  border-radius: 7px;  color: #000000;  font-size: 1rem;  padding: 0.75rem 1.25rem; > 

These are some basic styles to create an outlined button. Import the Button.module.css file in your React component and apply the button styling.

import React from 'react'; import styles from './Button.module.css';  export default function Button()   return (  button className=styles.button> type="button">  Click me  button>  ); > 

Thanks to how CSS modules work, the styles.button will apply a unique value to className attribute of the button element. Because of that, the styles for .button selector coming from Button.module.css won’t clash with other styles in the project if they also use a .button selector. Now let’s apply multiple classes from a CSS module to a single element. In this case, let’s create a modifier for the outlined button to make it filled instead.

.button.filled   background-color: #2779e4;  color: #ffffff; > 
div className=`$firstClass> $secondClass> thirdClass fourthClass`>>div> 

If you want to use a value from a variable, you can wrap it around $<> . Otherwise, write it as a string. It might seem like you can throw the modifier class right in there, but it won’t work.

/* ❌ Won't load styles for the 'filled' class in Button.module.css */> button type="button" className=`$styles.button> filled`>>  Click here  button> 

The filled class won’t match the .filled styles defined in Button.module.css . That’s because the filled class coming from CSS modules looks more something like this _filled_gjkwa_3 when rendered in your application. CSS modules work by creating a unique identifier for each class individually, even if the selector chains together multiple classes or nests them. So, to apply multiple CSS modules classes, you have to set the className to use both classes individually.

/* ✅ Will load 'filled' class styles */> button type="button" className=`$styles.button> $styles.filled>`>>  Click here  button> 
.button > .button.filled > .button.filled.active > 
/* 1️⃣ .button */> button className=`$styles.button>`>>1button>  /* 2️⃣ .button.filled */> button className=`$styles.button> $styles.filled>`>>2button>  /* 3️⃣ .button.filled.active */> button className=`$styles.button> $styles.filled> $styles.active>`>>3button> 

Using Nested Classes in CSS Modules

If you have a CSS selector that applies styles to an element only when it is a child of an element with a specific class like so:

.card   background-color: #ffffff;  border: 1px solid #cccccc;  border-radius: 10px;  box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px,  rgba(60, 64, 67, 0.15) 0px 2px 6px 2px; >  .card .body   padding: 1rem 1.25rem; >  .card .header   border-bottom: 1px solid #cccccc;  padding: 1rem 1.25rem; > 

In this case — .header and .body need to have a parent with a .card class. You have to specify the child class on the child element and the parent class on the parent for the styles to work.

import React from 'react'; import styles from './Card.module.scss';  export default function Card()   return (  div className=styles.card>>  div className=styles.header>>  h2>Card Titleh2>  div>  div className=styles.body>>Card Contentdiv>  div>  ); > 

The child styles are applied from styles.header property, although it might seem like they should be nested under styles.card.header instead.

Multiple and Nested Classes in SCSS

.button   background-color: #ffffff;  // ✂️  &.filled   background-color: #a84118;  > > 

This code will apply styles to an element with a .button class and an element with both .button and .filled classes. Using SCSS instead of CSS in CSS modules won’t change the way you apply multiple classes.

import React from 'react'; import styles from './Button.module.scss';  export default function Card()   return (  >  /* .button */>  button className=`$styles.button>`>>Onebutton>  /* .button.filled */>  button className=`$styles.button> $styles.filled>`>>Twobutton>  >  ); > 
.card   // ✂️  .header   // ✂️  >  .body   // ✂️  > > 
import React from 'react'; import styles from './Card.module.scss';  export default function Card()   return (  div className=styles.card>>  div className=styles.header>>  h2>Card Titleh2>  div>  div className=styles.body>>Card Contentdiv>  div>  ); > 

Источник

Читайте также:  Python установить время системы
Оцените статью