I am working on Switch component with antd library. I would like to change background of switch, so I have following code:
import styled from 'styled-components';
import { Switch as SwitchhAnt } from 'antd';
export const Button = styled(SwitchhAnt)`
.ant-switch-checked {
background-color: red;
}
`
But switch background does not change at all. I know I can wrap this in some container and it will works but why something like that does not works?
As per how styled components work under the hood,
It creates a unique class name by hashing styles into a seemingly-random string, like dKamQW or iDwMsQ.
Then inject a new CSS class into the page, using that hashed string as its name, and containing all of the CSS declarations from the styles string. You can see that when you inspect switch that different style classes have been applied.
Normal antd Switch
Styled antd Switch
So here you don't need to add the class name used by antd. Just only need to add CSS properties that need to have like below.
export const Button = styled(SwitchAnt)`
background-color: red;
// ....... other styles
`
You can check example codesandbox in here.
You can also refer demystifying-styled-components and how-styled-components-works for more details about what styled components do under the hood.
Related
I have a component called the amount component which is a shared library and I want to use that component in multiple places and I want to give that component different styles from where i use it. How to achieve it in angular ?
PS: amount component, needs styles for background, h2, button.
You can give custom styles to your account-component by adding an Input Attribute by using the #Input() Decorator & pass the styles or class name to that component depending upon where it is opened from.
Then you can use ngClass or ngStyle to apply those styles to your component.
For example in your account-component:
export class AccountComponent implements OnInit {
#Input() customClass: string;
}
Account Component HMTL
<div [ngClass]="customClass"> <h1>Account Component</h1> </div>
Account Component CSS
customClassRed:{
color: red;
}
customClassBlue:{
color: blue;
}
and in your components where you are opening account-component from just pass the class name (if you use the class name, then you need that class with styles in your components.css as I did above) or the styles depending upon your preferences
Another Component
<account-component [customClass]="customClassBlue"> </account-component>
I would like to know how to apply CSS dynamically to all the elements in a page that belong to a CSS class in React JS?
Currently I am using the following:
document.querySelectorAll('.my-paragraph-class').forEach(function (x: any) {
x.style.fontSize = `${data.value}%`;
});
It works but I would like to know if there is a more efficient way instead of using document.querySelectorAll?
Also when the page loads new text, document.querySelectorAll has to be called again after the text loads, which is not ideal. I would like to know how to persist the modified CSS changes when new text is loaded dynamically?
Thank you in advance
For applying a static font size to a class you shouldn’t have to use JavaScript at all.
In your css file just do:
.my-paragraph-class: {
font-size: 10rem || whatever;
}
To dynamically add styling you could use a CSS in JS tool like styled components. For styled components you would import styled components and then write a code outside of your react function like this:
const StyledParagraph = styled.p`
font-size: 10rem || ${props => props.fontSize}
`
In your JSX you would do something like:
<StyledParagraph fontSize=“10rem”> Filler Text </StyledParagraph>
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?
I'm working on a ReactJS app that has a header at the top, a menu on the left, and the "frame" in the middle is where routes and their corresponding components are loaded. I want to be able to apply a CSS stylesheet to specific components only when they are loaded. I also don't want them applied all the time or to the top header or left menu.
My expectation was that adding import 'custom.css'; to a specific component would only apply the stylesheet's styles to that component and it's children when the route is active. Instead, it applies it to the entire page even when the route/component are not loaded.
I understand that an alternative approach is styled components, but, for my use-case, a design company is supplying a stylesheet (which should remain unchanged) that we need to consume only for the sub-module I'm working on and I don't want its styles to affect the rest of the app.
How can I have a stylesheet only applied to my active route/component?
Use simple CSS technique. Suppose you have two components with different css files (say about.css and contact.css). Now consider your both CSS file have one common class with different style properties, like:
about.css
.container{
max-width: 400px;
}
contact.css
.container{
max-width: 500px;
}
Yes in ReactJS both the CSS files will load at the same time and will override any one of the style. so to solve this problem add class to differentiate this styles, like:
about.css
.about-component.container{
max-width: 400px;
}
contact.css
.contact-component.container{
max-width: 500px;
}
If you want apply only when the component is mounted, you can use the lifecycle.
The follow example is based in the idea you are using sass, React, sass-node and have the loaders into webpack.
<pre>
import React from 'react';
import './styles.scss';
class MyComponent {
constructor(props) {
super(props);
this.state = { className: '' }
}
componentDidMount() {
this.setState({
className: 'myOwnClass'
});
}
render(){
return (
<div className={this.state.className}>This is a example</div>
);
}
}
export default myComponent;
</pre>
To be able to only call that specific CSS when you need it you can use CSS Modules. You may need to update your version of react.
When saving your CSS file save it with a ".module.css" eg. "styles.module.css". The CSS in these files can only be used and accessed by hte components where are they are imported. As stated in a tutorial from W3Schools.
Let's say this is your CSS code in styles.module.css:
.container {
color: white;
}
.cont-child {
background-color: red;
}
Then in your JS file you can import the CSS file like this if the JS and CSS files are in the same directory. Make sure you point to the correct path.
import styles from './styles.module.css'
Then in your HTML section you can use it like this:
class Home extends React.Component {
render() {
return(
<main className={ styles.container } >
<div className={ styles["cont-child"]} >
Some div text about something...
</div>
</main>
);
}
}
I currently use both ways to access the selectors, since the styles variable acts like an object. I placed both of them here because the second option is capable of fetching selectors named like "btn-active". Which comes in handy in some situations. Camelcasing is considered cleaner though.
Please note: I originally posted this answer as a reply to a similar question here React CSS - how to apply CSS to specific pages only
I want to be able to apply a CSS stylesheet to specific components
only when they are loaded.
Why not apply the styles inline via React.js?
Step 1. Create the style object for the component:
var componentOneStyle = {
color: 'white',
backgroundColor: 'red'
};
Step 2. Populate the component's style attribute with the style object:
ReactDOM.render(<div style={componentOneStyle}>This is Component One</div>, mountNode);
I have several components which have the following CSS/component structure
About/style.css
.AboutContainer {
# Some style
}
p > code {
# Some style
}
And I import the CSS in the componet as follows
About/index.js
import './style.css';
export default class About extends Component {
render() {
# Return some component
}
}
However, the CSS is imported in the <header> section and stays global-scope.
I was expecting CSS to be:
Component-scoped in a way that the style is only applied to things that are only rendered within this component.
Style for this component would disappear if the component is unmounted.
However, when inspecting from the browser, the styles are specified at the <header> section and gets applied to all the components
<header>
// Stuff
<style type="text/css">style for component About</style>
<style type="text/css">style for component B</style>
<style type="text/css">style for component C</style>
// Stuff
</header>
How do I import CSS to be component-scoped? It seems like I'm understanding CSS import in React ES6 incorrectly.
I was following this tutorial
Edit
Answer by Brett is correct. However, my problem turns out to be somewhere else. I created my app using create-react-app which basically simplifies setups required to do React. It include WebPack, Babel and other things to get started. The default WebPack config that it uses did not set module option for the css-loader so it defaulted to false, and as a result the local-scoping was not enabled.
Just for additional info, it seems like create-react-app does not have straightforward way to customize WebPack config, but there seem to be numerous how-to workarounds on the web.
It sounds like CSS Modules, or many of the other CSS-in-JS packages, does what you want. Others include Emotion (my current favorite), Styled Components, or many of the packages here.
A CSS Module is a CSS file in which all class names and animation names are scoped locally by default. All URLs (url(...)) and #imports are in module request format (./xxx and ../xxx means relative, xxx and xxx/yyy means in modules folder, i. e. in node_modules).
Here's a quick example:
Let's say we have a React component like:
import React from 'react';
import styles from './styles/button.css';
class Button extends React.Component {
render() {
return (
<button className={styles.button}>
Click Me
</button>
);
}
}
export default Button;
and some CSS in ./styles/button.css of:
.button {
border-radius: 3px;
background-color: green;
color: white;
}
After CSS Modules performs it's magic the generated CSS will be something like:
.button_3GjDE {
border-radius: 3px;
background-color: green;
color: white;
}
where the _3DjDE is a randomly generated hash - giving the CSS class a unique name.
An Alternative
A simpler alternative would be to avoid using generic selectors (like p, code, etc) and adopt a class-based naming convention for components and elements. Even a convention like BEM would help in preventing the conflicts you're encountering.
Applying this to your example, you might go with:
.aboutContainer {
# Some style
}
.aboutContainer__code {
# Some style
}
Essentially all elements you need to style would receive a unique classname.
Maybe react-scoped-css will help. Btw, I'm the author of this lib, if you find anything broken or simply want to improve it, you can always raise an issue or send a pr.
Because you mentioned you used create-react-app, the solution here is quite easy change just style.css to style.module.css, it will look like this:
import styles from "./style.module.css"
<button className={styles.button}>blabla</button>
More info on this article:
https://blog.bitsrc.io/how-to-use-sass-and-css-modules-with-create-react-app-83fa8b805e5e
You can use SASS (.scss) to imitate scoped CSS.
Say you need to use bootstrap in only one component (to avoid conflicts). Wrap the component in <div className='use-bootstrap'> and then created a .scss file like so:
.use-bootstrap {
// Paste bootstrap.min.css here
}
Use this file naming convention [name].module.css
and see documentation: https://create-react-app.dev/docs/adding-a-sass-stylesheet
JSX File
import React from 'react';
import styles from './index.module.scss';
const MyPage = () => {
return (
<div className={styles}>
<h1>My Page</h1>
</div>
);
};
export default MyPage;
Styles File
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
For me, the simple solution (without using: Css-modules or css-in-js) is to add a suffix to your class selectors like this:
className="btn__suffix"
if your component is named: FileUpload.tsx so your __suffix would be __fu, i took the first character of each word (here: File and Upload).
the end result would be:
import './style.css';
export default class About extends Component {
render() {
Return (
<div className="container__fu">
...
</div>
)
}
}
And in the Css part, your file would be:
.container__fu {
...
}
I created a rollup plugin to have scoped scss/css within a vite react project with regular import, you can check it out if it can solve your issue!
https://www.npmjs.com/package/rollup-plugin-react-scoped-css