Pregunta

Introduction / background: CSS components

For a relatively large website we are working with SASS, and trying to manage CSS in components. The basic idea of components is that a component should look the same everywhere, independent of container elements further up in the DOM.

So, we want to avoid stuff like this (SASS):

// User picture component.
.user-picture {
  img {..}
}

// Override user picture for the frontpage.
body.page-front .user-picture img {..}

Instead, if we want the user picture to look different on the frontpage, it would have to be a different component. E.g. with SASS inheritance, or with a mixin:

// User picture component.
.user-picture {
  img {..}
}

// User picture on frontpage.
.user-picture-front {
  @extend .user-picture;
  img {..}
}

Then we need to adjust the html on the frontpage, so that it uses the different version of the user picture.

So far so good. I posted the above as an illustration of my current understanding of what CSS components are about.

The question: Modifier classes - good practice?

Now we are running into a problem: Some pages have a dark (black) background, and so the text, borders and stuff need to be white.

This somehow goes beyond components: The same component should have dark text by default, but white text if it is within a container with dark background.

So we have this awesome idea:

// Generic modifier class for all dark-background containers.
.white-on-black {
  // Generic text color change.
  color: white !important;
}

// Component.
.my-component {
  border: 1px solid blue;
  // Special for white-on-black.
  .white-on-black & {
    border-color: yellow;
  }
}

So we have an external "modifier" or "context" class white-on-black that modifies how the internal elements are displayed.

The motivation is that the component itself is not responsible for the background of a container element further up in the DOM.

This works. Only problem is if we have a white background container within the dark background container. But this aside, it works ok.

The question is whether this is architecturally a good practice, with the background of trying to keep the components independent of each other.

Alternative would be to have a different component, e.g. my-component-on-dark-bg, which inherits from my-component and has the different color for text and borders. But here the (e.g. PHP) code that produces the component html needs to know about the outside, that is, whether a dark bg is used. Assuming that the PHP code that renders the component is separate from the PHP code that renders the container. Which is still manageable, but could be an argument for the pattern with a modifier class, as described above.

Notes

We are actually prefixing our CSS classes with a project-specific prefix. I just left this out here for simplicity, and because it is nobody's business which project I am working on :).

¿Fue útil?

Solución

That seems like a perfectly defensible design. Compared to your proposed alternative:

  • There is less code duplication than creating a separate set of components for white-on-black.
  • It might get confusing and a bit messy if you have a lot of modifications for the white-on-black state.

I think it's a judgement call which design should be preferred, but I would go with your chosen design if the number of custom modifications of individual components for white-on-black was relatively small.

Licenciado bajo: CC-BY-SA con atribución
scroll top