1 year ago

#36177

test-img

suamikim

How to style a component "from the outside" with scoped css

I'm using scoped CSS with https://github.com/gaoxiaoliangz/react-scoped-css and am trying to follow the following rules (besides others):

  • Scoped component CSS should only include styles that manipulate the "inside" of the component. E.g. manipulating padding, background-color etc. is fine whilst I try to stay away from manipulating stuff like margin, width, flex etc. from within the component CSS
  • Manipulating the "outside" of a component (margin, width, flex etc.) should only be done by "consuming" or parent components

This is rule is somewhat derived from some of the ideas behind BEM (and probably other CSS methodologies as well) and allows for a rather modular system where components can be used without "touching their outside" but letting the parent decide how their internal layouts etc. works.

Whilst this is all fine in theory, I don't really know how to best manipulate the "outside styles" of a component from the consuming code which is best shown with an example:

search-field.scoped.css (the component)

.input-field {
  background: lightcoral;
}

search-field.tsx (the component)

import './search-field.scoped.css';

type SearchFieldProps = {
  className: string;
};

export const SearchField = (props: SearchFieldProps) => {
  return <input className={`input-field ${props.className}`} placeholder="Search text" />;
};

sidebar.scoped.css (the consumer)

.sidebar-search-field {
  margin: 16px;
}

sidebar.tsx (the consumer)

import './sidebar.scoped.css';
// ...

export const Sidebar = () => {
  return (
    <SearchField className="sidebar-search-field" />
    (/* ... */)
  );
};

In the above example, the CSS from the class sidebar-search-field in sidebar.scoped.css is not applied because the class passed to SearchField is scoped to the Sidebar and the final selector .sidebar-search-field[data-sidebarhash] simply doesn't match as the input element of the SearchField (obviously) doesn't have the data attribute data-sidebarhash but data-searchfieldhash.

ATM, I tend to create wrapper elements in situations like this which works but is rather cumbersome & clutters the markdown unnecessarily:

// ...
export const Sidebar = () => {
  return (
    <div className="sidebar-search-field">
      <SearchField />
    </div>
    (/* ... */)
  );
};

Question

Is there any way to "style scoped CSS component from the outside"?

Ps.: I'm not sure if all the above also applies to scoped styles in Vue. If not, please let me know how it works there so that I can create a feature request in https://github.com/gaoxiaoliangz/react-scoped-css.

css

reactjs

vue.js

scoped

0 Answers

Your Answer

Accepted video resources