, the issue with your code is that you're trying to mix CSS modules and dynamic styles, but CSS modules don't really work that way. They're more for static, predefined class names. But no worries, there's a simple fix.
You can just use inline styles for dynamic stuff. Inline styles let you plug in your JavaScript values directly into your style attribute.
Here's what you can do:
In your Hero.js, instead of trying to attach your prop to a CSS module class, you can directly use it in a style object. Something like this:
const Hero = ({ heroHeight }) => {
const dynamicStyle = {
height: heroHeight, // This is where your dynamic height goes
border: '1px solid green', // Assuming you always want this green border
};
return (
<div className={styles.pageWidth} style={dynamicStyle}>
{/* Your Hero content */}
</div>
);
};
When you use your Hero component, just pass the height like you were doing:
<Hero heroHeight="400px" />
Answer from soheil izadi on Stack Overflow, the issue with your code is that you're trying to mix CSS modules and dynamic styles, but CSS modules don't really work that way. They're more for static, predefined class names. But no worries, there's a simple fix.
You can just use inline styles for dynamic stuff. Inline styles let you plug in your JavaScript values directly into your style attribute.
Here's what you can do:
In your Hero.js, instead of trying to attach your prop to a CSS module class, you can directly use it in a style object. Something like this:
const Hero = ({ heroHeight }) => {
const dynamicStyle = {
height: heroHeight, // This is where your dynamic height goes
border: '1px solid green', // Assuming you always want this green border
};
return (
<div className={styles.pageWidth} style={dynamicStyle}>
{/* Your Hero content */}
</div>
);
};
When you use your Hero component, just pass the height like you were doing:
<Hero heroHeight="400px" />
You can't really pass values to css files. There are two ways you can do this.
You can however use the style attribute to pass the height dynamically.
'use client';
import styles from '../page.module.css';
import style from './Hero.module.css';
const Hero = ({ heroHeight }) => {
return (
<div className={`${styles.pageWidth} ${style[heroHeight.updateTheHeight]`} style={heroHeight}>
</div>
);
};
export default Hero;
reactjs - How to use global variables in CSS-Modules? - Stack Overflow
postcss - Update CSS Module variables from Javascript - Stack Overflow
CSS Modules with variable class names
sharing variables between css and js
This is how you do it with vanilla CSS Modules
// vars.css
:root {
--color-black: #222;
}
// myComponent.module.css
@import './vars.css';
.component {
color: var(--color-black);
}
The CSS-Modules documentation mentions variables here: https://github.com/css-modules/css-modules/blob/master/docs/values-variables.md
With this you can import variables as so:
@value colors: "../../main/colors.css";
@value primary, secondary, tertiary from colors;
which can be used in your css:
.main {
background-color: tertiary;
border-top: 30px solid primary;
}
To make this work postcss-loader and postcss-modules-values need to be added to your webpack config. See below:
{
test: /\.css$/,
use: [{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
plugins: [postcssModulesValues]
}
}
]
}
I would just use the default color vars on the element/body/whatever, then put the alternate theme colors in another class, and toggle the theme class via JS. Here's a demo.
$("button").on("click", function() {
$("body").toggleClass("foo");
});
body {
--red: red;
--blue: blue;
--yellow: yellow;
background: #ccc;
text-align: center;
font-size: 5em;
}
.foo {
--red: #ce1126;
--blue: #68bfe5;
--yellow: #ffd100;
}
.red {
color: var(--red);
}
.blue {
color: var(--blue);
}
.yellow {
color: var(--yellow);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="red">RED</span> <span class="blue">BLUE</span> <span class="yellow">YELLOW</span>
<br>
<button>click me</button>
I would have 2 sheets and conditionally switch between the two:
colours.scss
:root {
/* Status colors */
--error: #842A2B;
--success: #657C59;
--pending: #666;
--warning: #7E6939;
}
otherColours.scss
:root {
/* Status colors */
--error: #FF0000;
--success: #00FF00;
--pending: #6666FF;
--warning: #FF00FF;
}
then in your react code import them and use them as you wish:
import styles from 'colours.scss';
import alternativeStyles from 'otherColours.scss';
...
{this.props.useNormalStyle ? styles.myClass : alternativeStyles.myClass}
Solved
say I have different "level" classes with names like:
level_1 level_2 level_3
and I want to programmatically assign those classes to items that are rendered inside a loop and the items get assigned a level based on a variable. How can I implement this with CSS Modules?
I've tried things like
{`${styles.level_}${itemLevel}`}and
{"styles.level_".concat(itemLevel)}but neither works.
To be clear, I need a formula that will result in something like "styles.level_1" when itemLevel === 1, for example.
I usually just define the style as an arrow function that returns the style object, and pass in whatever parameters are needed for the style. There is a shorthand notation for returning an object literal from an arrow function that works nicely for this.
const style = () => ({});
Just remember to only use ternary operators if using the shorthand, otherwise you would just need to explicitly return an object.
So, for your style:
const dropzoneStyle = (isPreview) => ({
width: `200px`,
height: `200px`,
backgroundColor: `#1DA1F2`,
backgroundImage: (isPreview) ? 'url(/path/to/image.jpg)' : 'none',
});
This adds the image is isPreview is true, but keeps it blank if not.
Then in your component, call the function where the style goes:
return (
<div>
<Dropzone
{...otherProps}
style={ dropzoneStyle(isPreview) }
>
</div>
);
Assuming files[0].preview returns a file (image) URL, you should be able to set a new style and pass it to the Dropzone component.
Something along these lines:
const renderDropzoneInput = (field) => {
const files = field.input.value;
let dropzoneRef;
render() {
let dropzoneStyle = {
width: `200px`,
height: `200px`,
backgroundColor: `#1DA1F2`,
};
if (files[0]) {
dropzoneStyle = {
width: `200px`,
height: `200px`,
backgroundColor: `#1DA1F2`,
backgroundImage: `url(${files[0].preview})`,
// or to use a fixed background image
// backgroundImage: `url(/path/to/static/preview.png)`,
backgroundPosition: `center center`,
backgroundRepeat: `no-repeat`
};
}
return (
<Dropzone
name={field.name}
ref={(node) => { dropzoneRef = node; }}
accept="image/jpeg, image/png"
style={dropzoneStyle}
/>
)
}
}
a spread operator could be used to DRY this code a bit, with:
let dropzoneStyle = {
width: `200px`,
height: `200px`,
backgroundColor: `#1DA1F2`,
};
if (files[0]) {
dropzoneStyle = {
...dropzoneStyle,
backgroundImage: `url(/path/to/static/preview.png)`,
backgroundPosition: `center center`,
backgroundRepeat: `no-repeat`
};
}
With styled-components we can do something like:
```
const ContactButton = styled.button`
background: ${props => props.caseStudyColor};
color: #fff;
font-size: 2rem;
padding: 10px;
`;
<ContactButton caseStudyColor={'#004655'} /> ```
This can be pretty useful for maybe passing unique styles based on a condition to a component we return from a map function or something similar, but my question is, is there any way to do this without the use of styled-components???
Like this:
function Component() {
const style = { "--my-css-var": 10 } as React.CSSProperties;
return <div style={style}>...</div>
}
Or without the extra style variable:
function Component() {
return <div style={{ "--my-css-var": 10 } as React.CSSProperties} />
}
This works in both .tsx files and .d.ts files.
The key is to include import 'react' at the top. This turns the file into a module (even if it is a .d.ts file), allowing you to use Module Augmentation to extend the existing React types rather than overwriting them.
The Solution
Place this snippet at the top of your component file (.tsx) or in any definition file (e.g., types.d.ts).
import 'react';
declare module 'react' {
interface CSSProperties {
// Allow any CSS variable starting with '--'
[key: `--${string}`]: string | number
}
}
Usage
Now you can pass CSS variables to the style prop without TypeScript errors:
<div style={{ "--value": percentage, color: "var(--value)" }} />