javascript - hur definierar jag mer än ett stilnamn med css-moduler


Jag försöker använda flera klasser för ett element med CSS-moduler. Hur gör jag det?

function Footer( props) {
    const { route } = props;
    return (
        <div className={styles.footer}>
            <div className={styles.description, styles.yellow}>
              <p>this site was created by me</p>
            </div>
            <div className={styles.description}>
              <p>copyright nz</p>
            </div>
        </div>
    );
}

Svar #1

Du kan lägga till flera klasser med CSS-moduler på följande sätt:

className={`${styles.description} ${styles.yellow}`}

t.ex.

function Footer( props) {
    return (
        <div className={styles.footer}>
            <div className={`${styles.description} ${styles.yellow}`}>
              <p>this site was created by me</p>
            </div>
        </div>
    );
}

Med react-css-modules kan du använda normal syntax för klassnamn:

<div styleName='description yellow'>

och du anger allowMultiple: true för flera klasser

Svar #2

Du kan använda en array som kommer att slås ihop med ett mellanrum. t.ex

<div className={[styles.App, styles.bold, styles['d-flex-c']].join(' ')}>

Jag föredrar detta framför att använda template literals som @steven iseki föreslog eftersom det är lättare att lägga till och ta bort klasser utan att behöva omsluta dem i $ {} varje gång.

Men om du av någon anledning lägger till många klasser på många element kan du skriva en högre ordningsfunktion för att göra det enklare

import React from 'react';
import styles from './Person.module.css';

console.log(styles);
// sample console output =>
// {
//   App: 'App_App__3TjUG',
//   'd-flex-c': 'App_d-flex-c__xpDp1',
// }


// func below returns a function that takes a list of classes as an argument
// and turns it in an array with the spread operator and reduces it into a spaced string

const classLister = styleObject => (...classList) =>
  classList.reduce((list, myClass) => {
    let output = list;
    if (styleObject[myClass]) {
      if (list) output += ' '; // appends a space if list is not empty
      output += styleObject[myClass]; 
      //Above: append 'myClass' from styleObject to the list if it is defined
    }
    return output;
 }, '');

const classes = classLister(styles); 
// this creates a function called classes that takes class names as an argument
// and returns a spaced string of matching classes found in 'styles'

Användning

<div className={classes('App', 'bold', 'd-flex-c')}>

Ser mycket prydligt och läsbart ut.

När det renderas till DOM blir det

<div class="App_App__3TjUG App_d-flex-c__xpDp1">
/* Note: the class 'bold' is automatically left out because
   in this example it is not defined in styles.module.css 
   as you can be observe in console.log(styles) */

Som väntat

Och det kan användas med villkor genom att lägga de villkorligt genererade klasserna i en array som används som ett argument för klasser via ... spread-operatorn

Faktum är att medan jag svarade på detta bestämde jag mig för att publicera ett npm-modul eftersom varför inte.

Få det med

npm install css-module-class-lister

Svar #3

Jag rekommenderar starkt att använda classnames-paketet. Det är otroligt lättviktigt (600 byte minimerat) och har inga beroenden:

import classnames from 'classnames';

Function footer(props) {
  ...
  <div className={classnames(styles.description, styles.yellow)}>
}

Det har till och med den ytterligare fördelen att kunna lägga till klassnamn villkorligt (till exempel för att lägga till en mörk tema-klass), utan att behöva sammanfoga strängar vilket av misstag kan lägga till en undefined eller false-klass:

  <div className={classnames(styles.description, {styles.darkTheme: props.darkTheme })}>

Svar #4

Du bör lägga till hakparenteser för att göra classNames till en array, och för att ta bort ',' använd join().

function Footer( props) {
    const { route } = props;
    return (
        <div className={styles.footer}>
            <div className={ [styles.description, styles.yellow].join(' ') }>
              <p>this site was created by me</p>
            </div>
            <div className={styles.description}>
              <p>copyright nz</p>
            </div>
        </div>
    );
}

Relaterade artiklar