How to add multiple classNames to an html element when using scss in React - reactjs

I have a styles.module.scss file and a react component. How can add multiple classNames from the styles to ONE html element?
Below is my code:
/styles/styles.module.scss file
.gridContainer {
display: grid;
gap: 2em;
grid-template-columns: 1fr 25em;
grid-template-rows: auto;
}
.gridItem {
display: flex;
flex-flow: column;
}
.imageWithText {
border: 1px solid #4338ca;
border-radius: 1.6rem;
align-self: start;
}
/pages/infoPage.tsx file
import styles from "../styles/styles.module.scss";
export default function InfoPage({}: PageProps) {
<div className={styles.gridContainer}>
<div className={styles.gridItem}>
...
</div>
{/* I have added TWO style selectors here */}
<div className={(styles.gridItem, styles.imageWithText)}>
...
</div>
</div>
}
When I run this code, the div with TWO style selectors does not work as expected. The second classname={styles.gridItem} does not take the scss styles from the .gridItem selector. This div takes the styling only from the .imageWithText.
EXPECTED BEHAVIOR: I want the styles for both the .gridItem and the .imageWithText to apply to the second div.
I believe I am not writing the multiple selectors in the html element correctly and this has possibly got something to do with the way scss works. Any help would be appreciated.

You can try with backtic character (`), so your code :
<div className={`${styles.gridItem} ${styles.imageWithText}`}>

Related

CSS overlapping in React

I have 2 different pages and a .css file for each page. Both have a class selector with the same name, but only one of them is applied. I've only worked with react-native so far, and had both the content and the styling in the same file. I couldn't figure out what is happening...
Let's say we have the following css class:
.container {
display: flex;
align-items: center;
justify-content: center;
}
Even if the css file is not imported in one file, the class is applied to a div, if it's given in className.
For example, we have 2 files: CarPage.tsx and BikePage.tsx. The container class is imported in CarPage, but it's used in BikePage and it is applied. Does anyone know if this is how it should work?
In React, once CSS is imported, it will be "combined" and applied to the entire DOM. React uses CSS files as global scope.
In order to achieve locally scoped CSS, you will have to use:
CSS module
Create `[name].module.css` file then:
import React, { Component } from 'react';
import styles from './example.module.css';
class Example extends Component {
render() {
return <button className={styles.container }>Button</button>;
}
}
export default Example;
using libraries such as styled-components).
class Example extends Component {
const Button = styled.button`
background: transparent;
border-radius: 3px;
color: red;
margin: 0 1em;
padding: 0.25em 1em;
`
render(){
return <Button />
};
}

Overwriting MUI with scss

I'm working on a React project that uses MUI and Sass. Currently there are multiple scss-files full of !important to overwrite the MUI styles with sass. I tried to fix this by removing the !important's and adding:
import { StyledEngineProvider } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline'
<CssBaseline />
<StyledEngineProvider injectFirst>
*** component tree here ***
</StyledEngineProvider>
as suggested here: Issue with #Mui and modularized scss competing intermittently. How to consistently override #mui default styling with scss modules?
Which seemed to work at first but stops working when you focus on a component. For example this button turns white with a blue border when hovered over:
scss
.button {
width: 250px;
height: 50px;
border: 1px solid grey;
border-radius: 15px;
text-transform: none;
}
.go-button {
#extend .button;
background-color: grey;
color: whitesmoke;
}
reactjs
<Button
className="go-button"
variant="outlined"
onClick={handleClick}
>
Go
</Button>
We are not using modules or makeStyles. What would be the best way to overwrite MUI without the !important's?
The default styles for many MUI components will include some styles for specific states like :hover, .Mui-focused that have a higher specificity than the styles of the default state. When overriding those styles you need to use the same specificity.
For instance, Button has default styles specific to hover, so you will need to specify style overrides for the hover state.
For example, here's one possible way to define your button styles:
.button {
width: 250px;
height: 50px;
border: 1px solid grey;
border-radius: 15px;
text-transform: none;
}
.go-button {
#extend .button;
background-color: grey;
color: whitesmoke;
}
.go-button:hover {
#extend .go-button;
background-color: #999;
}
According to my knowledge experience, you must use styled-components with MUI because they have a better pair rather then SCSS, with better pair you have better performance of the website & with styled-components you can easily modify the changes of MUI.
Visit this link for advanced usage

Overwrite global scss class from module scss [duplicate]

Lets say in my global.css file of a Next.js project I have:
.flex {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
I also have a Layout.js component and a Layout.module.css file. The component looks like this:
import styles from "../styles/Layout.module.css";
const Layout = ({ children }) => {
return (
<div>
<div className={styles.navbar}>
<div className="flex">
<h1>Structured Safety</h1>
<nav>
<ul>
<li> Home </li>
<li> Demo </li>
</ul>
</nav>
</div>
</div>
</div>
);
};
export default Layout;
and the Layout.module.css is:
/* Navbar */
.navbar {
background-color: var(--primary-color);
color: #fff;
height: 70px;
}
.navbar ul {
display: flex;
}
.navbar .flex {
justify-content: space-between;
}
Structured like this, my .navbar .flex does not overwrite the global .flex class and split the h1 from the nav. How can I accomplish overwriting my global style from this component style?
Since .flex refers to a global class you'll need to use the :global selector to target it in your CSS module.
/* Layout.module.css */
.navbar :global(.flex) {
justify-content: space-between;
}
Or using an alternate syntax.
.navbar {
:global {
.flex {
justify-content: space-between;
}
}
}
/** CSS MODULE FILE **/
.classname :global(.globalClass) { css properties }
.classname {
:global {
.globalClass { css properties }
}
}
In NextJS and React when you
import styles from "__.css" the styles becomes a variable so you have to use it in your HTML for it to take effect.
Currently you're not using any styles from your Layout.module.css, if you want to use that css you would change your html to: <div className={styles.navbar}> and such..

Reactjs Module CSS multiple class selector

I'm trying to implement or add multiple class in out container when I click a button. But it seems that the styling is not being applied. Below are my code
Layout.module.css
.Content {
padding-left: 240px;
min-height: calc(100vh);
top: 0;
display: block;
position: relative;
padding-top: 80px;
background: #eee;
padding-bottom: 60px;
transition: padding-left 0.2s linear;
}
.Content.collapse {
padding-left: 100px;
display: block;
transition: padding-left 0.2s linear ;
}
Now I added the collapse class in my nav component like so
const layout = (props) => (
<Aux>
<Sidebar collapse={props.collapse} />
<div className={`${classes.Content} ${props.collapse ? 'collapse' : ''}`}>
<TopNavigation toggle={props.toggle}/>
{props.children}
<Footer />
</div>
</Aux>
);
So basically I'm just checking the props if it's collapse or not. If it is then I'll add a text collapse in the class.
Now when I click on a button it sets the state.collapse = true/false. It was able to do it's job. Now it seems that it's not reading my css style. Below is the generated class in my DOM
Notice the class .Content styling was detected. But as you can see here
Layout_Content__2WLOk collapse the div container has a class of collapse. So I was thinking it should read the .Content.collapse selector. Am I missing something here?
When using CSS modules, it creates a unique classname for each class for each instance of the component.
So you need to use the imported classes to have access to the generated classnames, just like you do for the .Content
So
<div className={`${classes.Content} ${props.collapse ? classes.collapse : ''}`}>
You are using a string not the generated hash
this part will not work
${props.collapse ? 'collapse' : ''}
Quick fix
Try not chaining it.
.collapse {
padding-left: 100px;
display: block;
transition: padding-left 0.2s linear ;
}
and add
classes.collapse instead of collapse
${props.collapse ? classes.collapse : ''}
In React you need to use the keyword 'className' instead of 'class'
https://reactjs.org/docs/dom-elements.html#classname
Also if you want to use CSS Modules you need to import your Layout.module.css file like this
import styles from './Layout.module.css';
And you can add CSS selector like this
<div className={styles.Content}></div>
you can study this here https://www.w3schools.com/react/react_css.asp

Styling React Bootstrap Component in Active State

I'm trying to style a React Bootstrap Navbar. I was able to successfully style the non-active tabs, however, I cannot seems to reach the active tab.
My styles live is a separate .scss file. Here's the relevant snippet:
.navitem {
a {
font-size: 12px;
color: #000;
background-color: #e7e7e7;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-bottom-color: #357ebd;
border-bottom-style: solid;
border-radius: 0px !important;
display: inline-block;
border-bottom-width: 2px;
}
flex: 1;
}
.navitem.active {
background-color: #777777;
}
When an active Bootstrap component is created, its HTML looks like this:
<li role="presentation" class="Preview-navitem--19fA7 active"><a role="button" href="#">Preview</a></li>
Here's the HTML inside the react render() method:
<Nav
className={styles.navbar}
bsStyle="pills"
activeKey={this.state.value}
onSelect={this.handleSelect}
>
<NavItem className={styles.navitem} eventKey="1">Preview</NavItem>
{navItem}
</Nav>
So, basically, I can style the .navitem, but not the .active.
Any idea how I could accomplish this?
Assuming this is CSS Modules, which it looks like based on the pasted code, the solution is to use global selectors. CSS Modules briefly mentions this on the main README page under Exceptions. However, their webpack demo has a global selector example you can clone and play around with.
In short, you should change:
.navitem.active {
background-color: #777777;
}
to:
.navitem:global(.active) {
background-color: #777777;
}
in order for it to be processed properly by Webpack. This should be all that's needed!

Resources