Home > database >  How does "classnames" work when there are multiple classes with same name
How does "classnames" work when there are multiple classes with same name

Time:10-02

I am reading some code where it is using npm utility classnames from https://www.npmjs.com/package/classnames.

In the scss file, it has multiple classes with the same name (small and large) like below:

.buttonA {
  &.small {
    height: 50px;
  }
  &.large {
    height: 80px;
  }
}

.buttonB {
  &.small {
    height: 20px;
  }
  &.large {
    height: 40px;
  }
}

This is the tsx file:

    <IconButton
      ....
      className={
        classNames('buttonA', 'small')
        }
     />

This confused me a lot as I am not sure which 'small' class it will choose to use, since we have 2 of them in scss. I suppose it would choose the 'small' class from buttonA, because it specifies buttonA as the first parameter? but that makes me wondering if these parameter are depend on each other? What if I do classNames('buttonB', 'small'), or, simply classNames('small')?

CodePudding user response:

I think the problem here is that you are overestimating what it is that classnames does and perhaps misunderstanding how CSS and/or Sass work.

classnames is simply a means of dynamically and conditionally concatenating strings. That's all it is doing-- it isn't interrogating and understanding any CSS that may be being applied to the className string values it is outputting. You don't even have to use it for className string values-- you could use it for other things like conditionally pluralizing messaging, like

const errors = ['this is required', 'that is also required'];
const numErrs = errors.length;
const errMsg = `You have ${numErrs} ${classnames('error', { s: numErrs > 1 })}`;

// errMsg is "You have 1 error" for a single error and "You have 2 errors" for two errors

Your Sass file is using the parent selector (&) to concatenate the inner rules to the parent container to create the following CSS output:

.buttonA.small {
  /* properties here will applied to an element with both `buttonA` and `small` class */
  height: 50px;
}

.buttonA.large {
  /* properties here will applied to an element with both `buttonA` and `large` class */
  height: 80px;
}

.buttonB.small {
  /* properties here will applied to an element with both `buttonB` and `small` class */
  height: 20px;
}

.buttonB.large {
  /* properties here will applied to an element with both `buttonB` and `large` class */
  height: 40px;
}

SO-- with these two concepts in mind:

  1. Your classnames('buttonA', 'small') will output the string "buttonA small", meaning that the element for which they are set as the className value will have the classes .buttonA and .small
  2. Understanding how the Sass file outputs CSS and how that CSS will be applied in the browser, the element will have a height of 50px
  • Related