jitendravyas / Q-A

7 stars 0 forks source link

How would one style a component differently based on its neighbours while using Atomic CSS #11

Open chinchang opened 6 years ago

chinchang commented 6 years ago

Heres an example when using default class-based approach:

<button class="btn">Hello</button>

When 2 buttons are required side-by-side as a group, we normally do:

<div class="btn-group"
 <button class="btn">Hello</button>
</div>

And in stylesheet we would have something like:

// Removing border-radius of buttons to show they are visually grouped.
.btn-group > .btn:not(:first-child):not(:last-child) {
 border-radius: 0;
}
.btn-group > .btn:first-child {
 border-radius-top-right: 0;
 border-radius-bottom-right: 0;
}
.btn-group > .btn:last-child {
 border-radius-top-left: 0;
 border-radius-bottom-left: 0;
}

Now coming back to Atomic CSS, our Button component would be something like:

<button class="Bgc(blue) Bdrs(4px) P(10px)">

To create above mentioned visual appearance of a button group, I could make a new Group component in which can wrap 2 buttons, like so:

<Group>
 <Button>Hello</Button>
 <Button>World</Button>
</Group>

But the issue is that, since each component has its classes(styles) on itself, the Group component cannot affect the inner buttons in any way. One way I can think of is: Atomic CSS's contextual class. Using that approach the Group can add a class which the Button component can refer as a contextual class.

<!-- Button -->
<button class="Bdrs(4px) Bdrs(0)__group">

Is this the best way to achieve my requirement?

thierryk commented 6 years ago

Relying on the config, you could do this:

"custom": {
  "Bdrs-start": "10px 0 0 10px",
  "Bdrs-end": "0 10px 10px 0"
}

the markup:

<div class="group">
    <button class="Bdrs(10px) group>Bdrs(0) group>Bdrs(Bdrs-start):fc group>Bdrs(Bdrs-end):lc">button</button>
    <button class="Bdrs(10px) group>Bdrs(0) group>Bdrs(Bdrs-start):fc group>Bdrs(Bdrs-end):lc">button</button>
    <button class="Bdrs(10px) group>Bdrs(0) group>Bdrs(Bdrs-start):fc group>Bdrs(Bdrs-end):lc">button</button>
</div>

This way you can pass the exact same classes to all your <Button> instances.

Note that this would be perfect if the classes were ugyified as it would creates much less bytes in the markup (even though Gzip is good when it comes to redundancy). In any case, in my article on Smashing Magazine I strongly suggest that adopting Atomic CSS methodology does not mean to "Atomic CSS all the things!". In the case of ACSS which—as you can see here—is very powerful, the idea is to know how to do any styling and then decide which approach makes more sense, and that mostly depends on the project.


Note that the "contextual" selector is used at the beginning of the class, not at the end.