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:
- Your
classnames('buttonA', 'small')
will output the string"buttonA small"
, meaning that the element for which they are set as theclassName
value will have the classes.buttonA
and.small
- Understanding how the Sass file outputs CSS and how that CSS will be applied in the browser, the element will have a
height
of50px