How to override global CSS in a CSS module file? - css

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..

Related

React component class styles not getting applied

I have a simple lightbox component that uses a material-ui modal and has a style sheet. The component and the css look like this.
Lightbox.tsx
import { Modal } from '#material-ui/core';
import { CloseOutlined } from '#material-ui/icons';
import styles from './Lightbox.module.css';
export default function Lightbox(props: any) {
return (
<Modal
className={styles.modal}
open={props.open}
onClose={props.handleClose}
>
<div className={styles.imageContainer}>
<div className={styles.imageToolbar}>
<CloseOutlined
aria-aria-label={props.closeButtonMessage}
className={styles.toolbarButton}
data-cy="lightbox-close"
fontSize="inherit"
onClick={props.handleClose}
role="button"
/>
</div>
<img src={props.url} className={styles.image} title={props.name} />
</div>
</Modal>
);
}
Lightbox.module.css
.modal {
z-index: 2147483640 !important;
}
.imageContainer {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.image {
max-width: 90%;
max-height: 90%;
}
.imageToolbar {
right: 10px;
top: 10px;
position: absolute;
width: 100%;
font-size: 40px;
}
.toolbarButton {
color: #cccc;
cursor: pointer;
float: right;
}
.toolbarButton:hover {
color: #ffff;
}
The component is rendered inside another component like so:
<Lightbox
closeButtonMessage={formatMessage(closeMessageDescriptor)}
url={url}
name={name}
handleOpen={handleOpen}
handleClose={handleClose}
open={open}
/>
When the application is run, the class names are present on the elements however, the styles are missing.
Elements in debugger console: Rendered elements
Rendered CSS for the elements: Style not rendering for the class
What am I doing wrong?
Please note that I need to use CSS style sheet as mentioned in my example and not inline CSS styles.
Since I am new to react, I have tried looking at other components in the project I am currently working on. This method of using CSS style works for other components. Since I am new to React, any help is appreciated.

When scoped in Nuxt.js, child elements are not styled

I'm using v2 of Nuxt.js.
If css is loaded under the following conditions, no style will be set on the child elements.
Import scss file with style settings with style tag
Add scoped to the style tag above.
Below is a demo.
CodeSandBox
It can be confirmed that the style for the elements under header in /assets/style.scss is not set.
header {
background: #dddddd;
> ul { // not working
list-style: none;
padding: 0;
display: flex;
}
button { // not working
background: black;
color: white;
}
}
Is there a way to style child elements in the form of importing scss?
The main codes are as follows.
<template>
<div id="app">
<Header />
<HelloWorld />
</div>
</template>
<script>
import Header from "./components/Header";
import HelloWorld from "./components/HelloWorld";
export default {
name: "App",
components: {
Header,
HelloWorld,
},
};
</script>
<style lang="scss" scoped>
#import "./assets/style.scss";
</style>
// Header.vue
<template>
<header>
<ul>
<li>
<h1>{{ appName }}</h1>
</li>
<li>
<button>Sign in</button>
</li>
</ul>
</header>
</template>
// style.scss
header {
background: #dddddd;
> ul {
list-style: none;
padding: 0;
display: flex;
}
button {
background: black;
color: white;
}
}
.hello {
background: #efefef;
padding: 1rem;
}
Its CSS will apply to elements of the current component only. So you need to append below code
<style lang="scss" scoped>
#import "../assets/style.scss";
</style>
at Header.vue to make the css file effected.

CSS Style not loading for the second container in NextJS

I have a two basic div containers and I am trying to apply some styles to it. I do import my CSS styles from a separate .module.css file and the first style gets picked up in the className property, when assigned. However, the same thing is not working for the second div. The css property for class 'sales' is not being picked up
dashboard.js
import HomeSalesmanStyles from '../../../styles/SalesmanHome.module.css';
const HomeSalesman = ({name}) => {
return(
<>
<div className={HomeSalesmanStyles.container}>
<h4>
Hello, {name} 👋
</h4>
</div>
<div className={HomeSalesmanStyles.sales}>
Hello
</div>
</>
)
};
export default HomeSalesman;
SalesmanHome.module.css
.container {
display: flex;
justify-content: center;
margin-top: 5%;
};
.sales {
display: flex;
justify-content: center;
width: 100px;
background-color: red;
}
Any ideas where the issue is?
----------- Edit ------------
The issue was wrong css module name import! After correcting to the right file, everything works.
This looks like a syntax error in the CSS: adding a semicolon after a rule is invalid.
.container {
display: flex;
justify-content: center;
margin-top: 5%;
} /* <- no semicolon */
.sales {
display: flex;
justify-content: center;
width: 100px;
background-color: red;
}
<div class="container">
<h4>
Hello, {name} 👋
</h4>
</div>
<div class="sales">
Hello
</div>

React components does not get effected by css

I create two components in React, and I want to display them both on the App component.
While they do show on the page, I can't use CSS to give each of them flex for example.
I want each component to take half of the screen size, this is what I have:
import "./App.css";
function App() {
return (
<div className="App">
<TopJourney id="Top-journey-section" />
<JourneysSection id="Journeys-section" />
</div>
);
}
export default App;
This is the App.css:
.App {
text-align: center;
display: flex;
flex-direction: column;
}
#Top-journey-section {
flex: 1;
}
#Journeys-section {
flex: 1;
background-color: greenyellow; // I added this just to be sure that the css does not work.
}
What is going wrong here?
You are passing id as a prop to your component, but you are not using it.
Wrong:
<TopJourney id="Top-journey-section" />
Good:
function TopJourney({id}) {
<div id={id}>your component stuff</div>
}
Your selectors id or className only works on native HTML elements, not on Components, try adding styles on HTML dom elements instead. For components, these are just regular props that you can use within the component.
This is a confusion of css flexbox column and row. it should be row and change the id into className, then.... change the css file as well below.
import "./App.css";
function App() {
return (
<div className="App">
<TopJourney className="Top-journey-section" />
<JourneysSection className="Journeys-section" />
</div>
);
}
export default App;
CSS file should be looks like this
.App {
text-align: center;
display: flex;
flex-direction: row;
width:100%;
}
.Top-journey-section {
width:50%;
}
.Journeys-section {
width:50%;
background-color: greenyellow; // I added this just to be sure that the css does not work.
}

&. doesn't work in SCSS... why not?

I'm writing some basic SCSS. But I've noticed appending & before a class, only works in certain circumstances. For example, before elements like "section" or before ":hover, active".
But this never works for me before ".class". Why not?
For example, in the below code, .flex-item styles only apply, if I remove the &. But look at docs/internet, it should work with & in front, no?
section {
padding: 20px;
margin: 0 auto;
border: 1px solid red;
position: relative;
width: 95%;
list-style: none;
top: 100px;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: center;
&.flex-item {
border: 1px solid green;
padding: 5px;
width: 50%;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: $white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
}
AND HERE'S THE JSX:
I basically want a section, (as that has high applied). And then two flex items, which sit side by side in a row, with the flex container...
<section className="flex-container">
<div className="flex-item">
<h1>A cashback credit card for holiday and home</h1>
<ul className="pros">
<li>No fees for making purchases abroad</li>
<li>Nothing added on top of the Mastercard exchange rate</li>
<li>Manage your holiday spending with realtime in-app notifications</li>
<li>0.5% cashback on all purchases above £1</li>
<li>Friendly customer support from anywhere with with in-app chat</li>
</ul>
<p>Great the same great rewards on holiday and at home with the Travel Cashback Credit Card.</p>
<p>See full information</p>
<Link to="/page-2/">Go to page 2</Link>
</div>
<div className="flex-item">
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
<Link to="/page-2/">Go to page 2</Link>
</div>
</section>
);
export default IndexPage;
Just remove the & before the .flex-item:
section {
// your section rules
.flex-item {
// your .flex-item rules
}
}
You only need the & (parent element reference) in cases where you want to use a pseudo selector, adding classes to the current selector (or partial class names), link a :hover or doing some other parent selector usage:
a {
// your link styles
&:hover {
// your hover styles
}
}
.button {
// .button styles
&.colored {
// .button.colored styles
}
&-large {
// .button-large styles
}
}
Or for some other parent selector appliances:
section {
// some styles
.parentclass & {
// this will match .parentclass section
}
}
This are just a few examples.

Resources