Basically, I am using different css files for a reason. My problem is that when I am styling something in one css file, it affects some other components I have, not only the one where I import this css file.
I think the problem is with react-router. I think it shares css files from every component i import to it. When I stop using a component in router, then its css files are not shared.
But how do I do routes different way? I need to import all components to router to have links to my pages.
I also tried to put routes into seperate files, it didn't help as well.
That's how my file with routes looks like:
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route
} from 'react-router-dom';
import './App.css';
import LoginPage from '../pages/LoginPage.js';
import Navbar from './Navbar.js';
import MainPage from '../pages/MainPage.js';
import SportsfieldsListPage from '../pages/SportsfieldsListPage.js';
import MyProfilePage from '../pages/MyProfilePage.js';
import SingleObjectPage from '../pages/SingleObjectPage.js';
import ConfirmPage from '../pages/ConfirmPage.js';
import AdminPage from '../pages/AdminPage.js';
class App extends Component {
render() {
return (
<Router>
<div className="container">
<Navbar />
<Route exact path="/" component={MainPage} />
<Route exact path="/listaBoisk" component={SportsfieldsListPage} />
<Route exact path="/LoginPage" component={LoginPage} />
<Route exact path="/MyProfilePage" component={MyProfilePage} />
<Route path="/object/:id" component={SingleObjectPage}/>
<Route path ="/confirm/:id/:value" component={ConfirmPage}/>
<Route path ="/adminPage" component={AdminPage}/>
</div>
</Router>
);
}
}
export default App;
You can use CSS modules for your project CSS Modules.Using this, unique class names are generated.
If you dont want to do this, then u you can use CSS class nesting, for eg:
For Main Page Component
<div className="main-page">
<div className="title">Main Page</div>
</div>
use css like this:
.main-page .title{
color:red;
}
Similarity for other components use css like this
.login-page .title{
color:green;
}
This way, your css styles will not get mixed up
Related
I am trying apply a margin-top as a CSS class to my beginner react-project. However, the margin is not applying. Wondering if someone can clarify if something is wrong? I used create-react-app to create and in the package.json file, it says my react-scripts is 4.0.2 so I believe this is supported. Just not sure what I am doing wrong.Every content that is in a div, p-tags , etc are displaying fine. I just can't get the classes to apply.
.Content {
margin-top: 16px;
}
import React from 'react';
import Aux from '../../hoc/Auxillary';
import classes from './Layout.css';
const layout = (props) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main className={classes.Content}>
{props.children}
</main>
</Aux>
);
export default layout;
Change this:
import classes from './Layout.css';
To
import './Layout.css';
Then change this:
<main className={classes.Content}>
to
<main className={"Content"}>
If you're bent on importing your css file like so:
import classes from './Layout.css';
Change your CSS file name to ./layout.module.css, then import it this way:
import classes from './layout.module.css';
And only then can you access css class names using:
classes.Content
More on file naming conventions here: https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
When I route my app to another component by using react-router-dom, the CSS doesn't change.
This is a minimalistic version of the code to demonstrate
App.js
import React from 'react';
import Home from './Home';
function App() {
return (
<div>
<Home></Home>
</div>
);
}
export default App;
Home.js
import React from 'react';
import './Home.css';
const Home = () => {
return (
<h1>Home</h1>
);
}
export default Home;
Home.css
body {
background-color: blue;
}
Dashboard.js
import React from 'react';
import './Dashboard.css';
import React from 'react';
import './Dashboard.css';
const Dashboard = () => {
return (
<div className='content'>
<h1>Dashboard</h1>
</div>
);
}
export default Dashboard;
Dashboard.css
.content {
display: flex;
align-content: center;
align-items: center;
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Dashboard from './Dashboard';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter as Router, Route } from 'react-router-dom';
ReactDOM.render(
<Router>
<div>
<Route exact path='/' component={App} />
<Route path='/dashboard' component={Dashboard} />
</div>
</Router>, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: ...
serviceWorker.unregister();
When I do /dashboard, it loads the Dashboard component, but it keeps the previous CSS that was loaded from the Home component that resides the App component. The background stays blue. I want that when I route to another component because I changed the URL, it loads whatever CSS that new component has attached to it and gets rid of whatever CSS was before. Is that possible?
Edit: I have made an example in CodeSandbox to illustrate. It's a little different from the code above due to the limitations of the playground, but the functionality is the same.
From what can be seen, importing as a module ends up importing it globally. If we comment the line import Home from "./Home"; the blue background disappears. Just importing the component, imports the whole CSS despite the CSS being imported in a modular way. I'm not sure if I am missing something.
Edit 2:
Here are the different solutions I tried:
CSS Modules, but the body style was still globally loaded.
Styled components don't let me modify the body or html selectors CSS. They require me to create a <div> element and
then have that element span the whole body which I would style
as if it was the body. Which is a workaround I don't want to use because for that I rather use CSS Modules for the whole body spanning .
Inline styling also doesn't let me modify the body or html selectors CSS. I would also need to use a workaround like a body spanning <div> as in Styled components.
The problem
When you import a css like you're doing here
import './Home.css';
you're importing it in a global scope, which means it will not disappear once imported.
The solutions
CSS Modules
What you want is either CSS Modules, which is used like this:
import styles from './Home.css';
<a className={styles.myStyleClass}>Hello</a>
Styled components
or a CSS-in-js framework such as styled components which is used like this:
import styled from 'styled-components';
const MyStyledElement = styled.a`
color: blue;
`;
<MyStyledElement>Hello</MyStyledElement>
Regular objects / inline styling
or just "regular" CSS-in-js like:
const myStyle = {
color: blue;
}
<a style={myStyle}>Hello</a>
There are plenty of options when it comes to styling, these alternatives are popular ones that I encourage you to explore and see which you enjoy.
After doing some more tests I have concluded that as of now it is not possible to change whatever CSS styles have been applied to a <body> or <html> selector in an React SPA when a CSS file is already loaded and one uses React Router to render other components. I still appreciate the answers and the time taken to help me find a solution. They are still valid answers if we are not talking about the <body> or <html> node in an HTML document. From them I learned about other ways to use CSS in React. I modified the original post with the solutions I tried.
What ended working was modifying the DOM styles with JavaScript whithin the component itself.
Home.js
import React from "react";
const Home = () => {
// Modify the DOM Styles with JavaScript
document.body.style.backgroundColor = "blue";
// Or uncomment below to modify the
// document root background color
// which in this case would be <html>
//document.bgColor = "blue";
// Or modify the root tag style of the document instead of the
// <body> (<html> in this case)
//document.documentElement.setAttribute('style', 'background-color: green');
return (
<div>
<h1>Home</h1>
<form action="/dashboard">
<input type="submit" value="Go to Dashboard" />
</form>
</div>
);
};
export default Home;
Here is a working example:
Where my app wasn't loading style sheets and the like. However, I was importing my assets directly into my index.html entry point.
By replacing the links with absolute paths as per this documentation, my problem was resolved.
For me, this meant changing
<head>
<link rel="stylesheet" href="./style.css" ></link>
</head>
to this:
<head>
<link rel="stylesheet" href="/style.css" ></link>
</head>
I'm not sure if the same thing would work for your import statements, but it is worth a shot.
More info: styles-not-working-with-react-router
I am quite new to react and react-router-dom. The problem is, I am trying to get different layouts for different routes in my application. But instead all of the css files for different routes just imported in one huge conflicting piece.
App looks like this:
<Router>
< >
<Navigation />
<UpButton />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/research" component={Research} />
<Route path="/publications" component={Publications} />
<Route path="/student" component={Student} />
<Route path="/about" component={About} />
</Switch>
</>
</Router>
Each component I am rendering looks like this:
import React from 'react';
import './home.scss';
// Utility
import Utility from 'components/utility/Utility';
class Home extends React.Component {
render() {
return (
< >
<Utility />
</>
);
}
}
export default Home;
Is there a way to import only the specific css file with specific route? Like home.css for '/' route, about.css for '/about' route specifically?
It might be the simple misunderstanding from me, but I really can't find any solution for now.
I recommend to use the following file structure and pattern:
- components
- Main.js
- Utility
- index.js
- styles.scss
- pages
- HomePage
- index.js
- styles.scss
Then specify the component related styles within the component's stylesheet, and the page-realated styles within the page's stylesheet. And use pages for routes, not components.
Finally, wrap every component into a specific class selector, and add wrap the belonging sass file into that selector (like .home-page).
For this reason, please, use sass instead of css, because you can embed style definitions within each other and use the top one as a "namespace". So the styles will not affect to each other.
// Main.js
import HomePage from '../pages/HomePage';
<Switch>
<Route path="/" exact component={HomePage} />
<Route path="/research" component={ResearchPage} />
// HomePage/index.js
import Utility from './components/Utility';
import './styles.scss';
...
render(){
<div className="home-page">
<Utility />
</div>
}
// HomePage/styles.scss
.home-page {
...
}
// Utility/index.js
import './styles.scss';
...
render(){
return (
<div className="utility-comp">
...
</div>
}
// Utility/styles.scss
.utility-comp {
...
}
React made a SPA which mean: single page application.. all the resources are loaded on app startup, if other resource are loaded in a second moment this resources became available in the entire applications.
I think that to avoid conflict you need to work on better target your stile, for example you can wrap your page in a container with the pagename as class, for example:
class Home extends React.Component {
render() {
return (
<div classname="home">
<Utility />
</div>
);
}
}
class Contact extends React.Component {
render() {
return (
<div classname="contact">
/*...*/
</div>
);
}
}
and then target your css using the page class:
.home h1{
color:red;
}
.contact h1{
color:blue;
}
I am using the latest ReactJS with Create React App + Typescript, and I am using CSS modules. The App architecture would be:
/components
SignIn/
SignIn.module.scss
SignIn.tsx
ResetPassword/
ResetPassword.module.scss
ResetPassword.tsx
Inside each FC component, I include the CSS like this:
SignIn Component
import React from 'react';
import styles from './SignIn.module.scss';
const SignIn: React.FC = props => {
...
return {
<div className={styles.container} />
}
}
...
ResetPassword Component
import React from 'react';
import styles from './ResetPassword.module.scss';
const ResetPassword: React.FC = props => {
...
return {
<div className={styles.card} />
}
}
...
I define react-router-dom like this...
...
<BrowserRouter>
<Switch>
<Route path='/sing-in' component={SignIn} />
<Route path='/reset-password' component={ResetPassword} />
</Switch>
</BrowserRouter>
...
The issue:
React inserts the <style> of each component regardless if I am in the Sign-in page or in the reset-password page.
Expected behaviour:
React inserts only the CSS for the component displaying in the current page.
I have tried to add the prop exact in each Route but it didn't work.
I have my "App-component" and a "B-component" that gets rendered inside my app component. Each has its own style.
But when it gets compiled, my ComponentB.css is put before my app.css, making the ComponentB styles being overwritten by my app styles.
Why is this happening??
APP
import React, { Component } from 'react';
import ComponentB from './components/ComponentB';
import './styles/app.css';
class App extends Component {
render() {
return (
<div className="App">
<ComponentB />
</div>
);
}
}
export default App;
COMPONENT B
import React, { Component } from 'react';
import './styles/ComponentB.css';
class ComponentB extends Component {
render() {
return (
<div>
<h1>Hello from ComponentB</h1>
</div>
);
}
}
export default ComponentB;
The way you do it results in a styles conflicts(one style overwriting another style), because after React compiles your code you are still using the same selectors for the same classes.
If you want to use different css files for different components while using the same class names, you should use CSS modules.
This will make your CSS class names scoped locally by default.