Emotion: Emotion generating n different classes not having a common class based on props

Created on 20 Mar 2020  路  7Comments  路  Source: emotion-js/emotion

Hi I'm rendering a list of items with background color as props.

const Thumbnail = styled.div<{ url: string }>`
  background-color: url('${props => props.color}');
  border-radius: 2px;
  height: 104px;
  margin-bottom: 8px;
  width: calc(33.33% - 5px);
`;

used as

<Thumbnail url={img.thumbnailLink} key={index} />

Emotion generates entirely different classes for all the Thumbnail components, is it the expected behaviour, what I was expecting was emotion generating 2 classes here
One for the common styles

  border-radius: 2px;
  height: 104px;
  margin-bottom: 8px;
  width: calc(33.33% - 5px)

and one based on prop value

background-color: red

Any help will be appreciated

question

Most helpful comment

Yes, both classes would have common properties but it doesn't mean that contents of both would appear anywhere in the code unless you are talking about SSRed output. I don't see this really as much of an issue - compression should deal with those nicely and usually when SSRing you don't necessarily produce tons of different rules, sure - there are some, but only what is actually used by the current SSRed screen, nothing more than that.

All 7 comments

It is expected and it lets us overcome "insertion order problem" which is described here: https://emotion.sh/docs/composition

@Andarist
In my use case is the above example the right way to go about it ? I'm new to emotionjs hence the confusion

I stumbled upon the same problem. In my case I have an element representing a simple dot using these styles:

const dot = ({ position }) => css({
  position: "absolute",
  width: "8px",
  height: "8px",
  borderRadius: "100%",
  background: "#aaaaaa",
  ...position
});

So every time I create dot with unique coords (top, left, bottom, right) it creates a class with multiple unnecessary properties.

At this time I hack it using inline styling like so:

<div css={dot} style={{ top: -3.5, left: -3.5 }} />
<div css={dot} style={{ top: -3.5, right: -3.5 }} />

const dot = css({
  position: "absolute",
  width: "8px",
  height: "8px",
  borderRadius: "100%",
  background: "#aaaaaa",
});

However, I would love to see some kind of API that could dangerously allow me to split the classes for a lesser amount of code.

However, I would love to see some kind of API that could dangerously allow me to split the classes for a lesser amount of code.

What does it even mean? How an API like this would result in "lesser amount of code"?

What does it even mean? How an API like this would result in "lesser amount of code"?

If I understand it correctly, in that case above it would create two classes and they would have in common these properties.

position: "absolute",
width: "8px",
height: "8px",
borderRadius: "100%",
background: "#aaaaaa",

So the optimization (lesser amount of code) for me would be to separate the common properties into a class and put the varying properties into the second class. That would result in one common class for all elements and second class based on props.

Yes, both classes would have common properties but it doesn't mean that contents of both would appear anywhere in the code unless you are talking about SSRed output. I don't see this really as much of an issue - compression should deal with those nicely and usually when SSRing you don't necessarily produce tons of different rules, sure - there are some, but only what is actually used by the current SSRed screen, nothing more than that.

Oh ok, finally I wrapped my head around that and it sounds totally reasonable, thank you for the clarification!

Was this page helpful?
0 / 5 - 0 ratings