Material UI v5 styles applied to class does'nt apply? - javascript

I am trying to style the MUI slider,so I decided to style it using the className prop. But the style applied to the main class does'nt get applied,while rest other styles like 'hover' state get applied. If I remove all the classes and just style it using SX prop,everything works fine. But I want to keep the styles seperate into an external css file.
Below is my code :
App.css
.container{
margin-left: 30%;
margin-top: 20%;
}
/* This does'nt get applied */
.slider {
color: #ff0000;
width: 300px;
}
.slider:hover {
color: #2e8b57;
}
.slider > .MuiSlider-thumb {
border-radius: 1px;
}
App.js
import "./App.css"
import * as React from 'react';
import Slider from '#mui/material/Slider';
export default function App() {
return (
<div className="container">
<Slider className="slider" defaultValue={30} />
</div>
);
}

The problem is with Material UI style injection order. The custom styles do apply, but Mui styles are injected before the custom style so they doesn't have effect in this case.
This guide explain how to change the injection order:
https://mui.com/guides/interoperability/#css-injection-order

I don't know if it is required, but I use css modules and material-ui. You can rename your css file to
App.module.css
then import like so
import styles from "./App.module.css"
you can then use it like
<Slider className={styles.slider} defaultValue={30} />
In Nextjs you can throw everything in styles.css to make it global, but I don't know if that is also for react as well.

Related

Dynamic import vite css

I have a theme option I capture via API call. I want this theme to correspond with css files (or combinations of them) I have created in the Vue 3 app (using vite).
These theme files I would like to 'layer' so I can have base.css, and style5.css which would append to that.
I'm also using tailwind.
main.pcss
/* tailwind base */
#import 'tailwindcss/base';
#import 'tailwindcss/components';
#import 'tailwindcss/utilities';
The current way I'm doing this (below) I don't like it for several reasons, but it was the only way I could get it working where the CSS would import properly, and would not cause a FOUC. I want the component and the css to load together.
So these are the things I'm hoping to achieve
No FOUC as the sheets load in the order I specify
They use global class styles (not scoped), compiled by tailwind with #apply, etc.
I would love to remove the component entirely and just import CSS files, to remove this layer of indirection, but when I tried that with yarn build the layout had none of css applied.
Should multiple separate css files I can combine, like base.css, style1.css style1.css, style2.css (if I want to make 1 tweak to style 1). As you see below I can't layer them, they just have to be copy pasted in full which is obviously not ideal
I want to make sure each 'theme' (group of css) is bundled and not all themes are bundled together (for file size reasons). This is why im using the async component
My layout component
<template>
<component v-if="theme" :is="themeComponent">
<slot />
</component>
</template>
<script>
import { computed, defineAsyncComponent } from 'vue';
import { useStore } from '#/store';
export default {
setup() {
const store = useStore();
const theme = computed(() => store.theme);
const themeComponent = defineAsyncComponent(() => {
if (theme.value === 'STYLE_1') return import('#/themes/Style1.vue');
if (theme.value === 'STYLE_2') return import('#/themes/Style2.vue');
return import('#/themes/StyleDefault.vue');
});
return {
theme,
themeComponent,
};
},
};
</script>
Here is my Style1.vue component:
<template>
<slot />
</template>
<style>
/* font */
#import url('https://fonts.googleapis.com/css2?family=Inter:wght#400;500;600;700&display=swap');
/* base */
body {
#apply text-slate-800 bg-white;
font-family: 'Inter', sans-serif;
}
.link {
#apply hover:underline;
}
.wrapper {}
.container {
#apply px-4 mx-auto max-w-[750px];
}
.header {
#apply bg-gray-50;
}
.content {
#apply pb-20 border-t-2 border-b-2 border-blue-300 ;
}
...
You can import your CSS file directly:
if (theme.value === 'STYLE_1') {
import('#/assets/styles/style1.scss')
}
But, since you import your CSS dynamically, there is no way to avoid FOUC. Because the CSS is loaded after JS and after the DOM loaded

component next/image are not working with CSS

I was trying to make border around an image and my custom css was not working because of Image component css, it was overriding over my custom css and also applied tailwind and bootstrap to fix it but I was unable to fix it. Now I am not getting any clue to fix it I read some github issues but they are not enough to fix it.
code:code link
Example of how to use :global(_selectors_here_) with !important:
import Image from "next/image";
import sli from "./sl.png";
export default function IndexPage() {
return (
<div>
<Image className="ava" src={sli} alt="hello" />
<style jsx>{`
:global(.ava) {
border: 3px solid red !important;
}
`}</style>
</div>
);
}
To make className work in external component, you have to either use :global or the resolve tag.
And to override inline styles, with tailwindcss, you can use important modifier like !border.

Changing the CSS for a React component has effect on all other pages

I have a React component with the following files:
src/components/HomePage/index.js
src/components/HomePage/style.scss
The component is very simple:
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className="homepage">
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
Within style.scss I am applying a style to all <h1> tags:
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
And it works as expected. However, I now see that the h1 style within styles.scss is being applied to every h1 on my site, even on pages that do not use this component.
I am using Gatsby, but it's a React app at heart. My understanding is that React's code-splitting feature would take care of this, that the code from style.scss would only be included in bundles for any page that uses my component.
It's the why that I am asking about. I have two easy fixes:
Wrap everything in style.scss in a .homepage wrapper
Use CSS modules and rename the file to style.module.scss. When I see people do that they always do `import style from './style.module.scss' - is there a way to have CSS modules without assigning it to an object like that?
Update: Coming back to this question after spending a lot of time with React and I think there's a gap in the market for React styling. CSS modules is syntactically poor in my opinion and having to manually wrap everything in a .home tag to localise it is manual work I don't want to do. Someone should really create a React plugin that automatically does this so that whenever I have a file called Home.js and I import Home.css that all the CSS is automatically restricted to Home.js without me having to do anything special.
If you want to localize CSS rules, then you would have to switch to modular stylesheets (works the same for sass stylesheets).
In your current structure, the component imports non-modular stylesheet and doesn't localize the changes with a unique identifier. Therfore added rules live in a global scope without a unique identifier that would localize them so that only selected components could understand them. That means that they are capable of easily overwriting the same-named rules which were previously established (import order matters here, because it would dictate how the bundler appends the output stylesheet).
So instead of holding component-related rules within ./style.scss file, rename it to ./index.module.scss and then you would utilize it within the component like so:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1 className={style.heading}>Landing page</h1>
</div>
);
};
export default HomePage;
and your stylesheet would look like:
.heading {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
disclaimer:
I've changed the styling convention from selecting elements by their tag, to selecting them by class, because targetting elements by tag is widely considered a bad practice [ref] , but if you want to maintain it, then you would have to provide a parent scope for such a rule (it already exists since the parent <div/> element has an assigned class.
In this case the implementation would look like:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
and styles:
.homepage {
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
}
You can either go with the easiest way that is mentioned below.
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className = "home">
<div className="homepage">
<h1>Landing page</h1>
</div>
</div>
);
};
export default HomePage;
You can wrap whole html inside one div of particular component name
CSS:
.home h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
This is the easiest way. However this is my personal solution because I also face the same issues when I was beginner at react.

How to update style of a React element with className

So I'm using Ant Design UI library with my create react app which is making it difficult for me to edit the style of more complicated Ant Design components. Like the progress bar is by default blue:
I want to make it another color and when I look at HTML in the Chrome console I see:
The className for that element is ant-progress-bg. Is there any way I can write some code in my React component and update the style to be from style={width: "12.5%, height: 8} into style={color: 'red', width: "12.5%, height: 8}?
This is all the React code I need to write to generate the Progress bar using the ant design library:
import { Progress } from 'antd';
<Progress
percent={percentVotes}
showInfo={false}
status="active"
/>
I've also tried importing CSS and added an "ant-progress-bg" CSS class with the styling I want but it didn't do anything.
In my Matches.css file I have:
.ant-progress-bg {
color: red;
}
which I import into my Matches.js file with import './Matches.css';
Here is a demo https://codesandbox.io/s/k0m0nl1my3
If you want to change progress bar color for all places then override this class
.ant-progress-bg {
background-color: red !important;
}
And if you want to change color only for this specific progress bar, add some extra class like
.my-progress-bar .ant-progress-bg {
background-color: red !important;
}
If you are using less for your custom styles, it's even simpler
.my-progress-bar {
.ant-progress-bg {
background-color: red !important;
}
}
<Progress
percent={percentVotes}
showInfo={false}
status="active"
className="my-progress-bar"
/>

How can I use a .css stylesheet in React?

So I have a very large stylesheet and I'm attempting to use it in my React code. I know typically you would use this format for styling in React:
transparentBg: {
background: 'transparent'
},
WhiteText: {
color:'white'
},
However, my css stylesheet looks like this:
.transparentBg{
background: transparent;
}
.WhiteText{
color:white;
}
Is there anyway to convert my entire CSS stylesheet into that React-style format? Or a way for me to just use the original CSS stylesheet without converting it?
Your CSS is still just CSS and React still just renders HTML elements on the page.
This means that you can add your large CSS file into html file and just add CSS classes / ids etc. that you define there to the elements in React.
So if you have
.transparentBg{
background: transparent;
}
.WhiteText{
color:white;
}
Then in your React components you can use these classes:
var SomeComponent = function () {
return <div className="WhiteText">
Foo Bar Baz
</div>;
};

Categories