How to influence foreign CSS classes when just using styled components - css

I am using react-table and I would like to apply CSS rules to the class rt-td which is not accessible nor modifiable through what their API offers.
In CSS I would just overwrite the CSS class from within my stylesheet. But how do you that with styled components? I heard it's an anti pattern, but what else should I do?

Suppose the parent of the the component ReactTable exported by react-table is a simple div.
const Test = () => (
<div>
<ReactTable someProperty={someValue}/>
</div>
)
you can influence the style of the class rt-td inside ReactTable by 1) converting the parent of ReactTable into a styled-components and 2) injecting style to override rt-td into the CSS of the aforementioned parent.
const Parent = styled.div`
.rt-td {
/* your custom style goes here*/
}
`
const Test = () => (
<Parent>
<ReactTable someProperty={someValue}/>
</Parent>
)
Usually that does the trick. If the style definition for rt-td inside react-table still overrides your custom definition due to specificity, keep repeating the class name rt-td inside Parent (like this .rt-td.rt-td) until your custom style wins.

Related

Chain selectors for custom module styling in Next JS not working

Chaining selectors in css file doesn't seem to apply styles. I am importing the styles in the component and it only applies for the main class, for example:
import styles from './Home.module.css'
const Home = () => {
return (
<header className={styles.header}>
<div className={styles.headerContainer}>
...
and than in Home.module.css I have:
.header {
// some styles that are getting applied
}
.header .headerContainer {
//some styles that don't show up
}
On the page I am able to see header that is styled but not the headerContainer. So I understand that Next js automatically adds some variables to the end of the classes when passing styles item to jsx but trying to understand how I would chain the selectors in css and be able to use styles in such way in Next JS.

How to use components in different ways (React)

I want to use simple components in different way and different ui rendering
For example a dropdown rendering a list may have several ui according to the page or context (=> padding, margins, font size and other css properties might change)
should I:
implement it by overwriting in the parent component (target css properties of the child component and apply them my css needs - at cost that if change happens in the child component like change in classname or what might break the parent design)
Pass flags to the component to handle those design and at cost that each component handle the design of each parent
There are different approaches to this and everybody has his own preferences.
I usually solve this by supporting the className property. The class is accepted as a prop and applied to the root. So it is easy to change things like outer margins or the background-color. I usually discourage modifications of deeply nested elements.
Example:
import classnames from 'clsx';
import style from './button.module.scss';
export const Button = ({ content, onClick, className }) => {
return (
<div
className={classnames(style.buttonRoot, className)}
onClick={onClick}>
{content}
</div>
);
};
and if I want to modify it anywhere I can do it thus:
import { Button } from './Button';
import style from './productView.module.scss';
// ...
<Button content={'Show products'} className={style.showProdButton} onClick={showProd} />
and
.show-prod-button {
background-color: #562873;
margin-left: 32px;
}

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.

React/Typescript, Styled Components, issues on injecting class definition

I have a React app where a Styled Components have some styles. My goal is to dynamically add a CSS class definition (such as .color-red{color:red}) to this style. I don't want to dynamically change a CSS property but append a whole CSS to the existing one.
My Styled Component is
const LayoutWithGlobalStyle = styled.div<GlobalStyledType>`
${props => (
`.test{background-color:red}
color: lightgray;
${props.add}
`
)}
`
and it's used this way
<LayoutWithGlobalStyle add={globalStyle} id="layout-content-container" >
The GlobalStyledType is
type GlobalStyledType = {
add: any;
};
At the beginning everything is working fine and the class eiEXnh is assigned to the LayoutWithGlobalStyle but when the variable globalStyle changes (it is passed through Redux) a new classname is assigned to the LayoutWithGlobalStyle, the new value is not added to the new class, all the previous CSS (.test{background-color:red} and color:lightgray;) is cleared and not present in the new class.
Any idea?

Best way to override child styles in styled-components

I have a Component and I want to override it's styles. I have used styled-components to build them.
My doubt is, how can one override styles of a child component.
I want to know better approach.
Example
const Child = styles.div'
font-size: '10px'
'
const Wrapper = styles.div'
color: red
'
const DummyComponent = () => (
<Wrapper>
<Child>Hello</Child>
</Wrapper>
)
I want to change padding or margin or any other property of child.
What is the better approach.
Using inline style or className. Or is there any better approach in styled-component to do this.
Using inline style
const DummyComponent = ({childStyles}) => (
<Wrapper>
<Child style={{...childStyles}}>Hello</Child>
</Wrapper>
)
Using className
const DummyComponent = ({childClass}) => (
<Wrapper>
<Child className={childClass}>Hello</Child>
</Wrapper>
)
I would recommend to use classNames to override the behaviors. you just need your rules stronger. tex:
const DummyComponent = ({childClass}) => (
<Wrapper className="div--wrapper">
<Child className="div--child">Hello</Child>
</Wrapper>
)
// css
.div--wrapper .div--child{
// override css go here
}
The CSS !important rule will override tags with higher precedence. For example, if you apply a class to the child element with the following code background-color: green !important; this will override other background-color rules that may be applied to the child element. This is the best way to override styles.

Resources