I have found some strange issue while making my website with React.
I have organized my filesystem into a folder of components-js and components-css with corresponding Text.js and Text.css files to match up.
Below are my Login.js/css and Signup.js/css files.
Login.js
import '../components-css/Login.css';
import Logo from './Logo.js';
import { useState } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import TextInput from './TextInput.js';
function Login(props) {
const [error, setError] = useState(false);
const navigate = useNavigate();
const trigger_error = () => {
console.log(error)
if (error === false) {
setError(true);
}
else {
setError(false);
}
}
const check_login_info = () => {
// TODO: Insert code here to check for username and password match
navigate('/Jobs')
}
return (
<div className='login-card'>
<div className='login-card-image'>
</div>
<div className='login-contents'>
<Logo/>
<div className='login-contents-header'>
Sign In
{error ? <p className='error'>Invalid Login. Please try again.</p>: <></>}
</div>
<TextInput label={'Email'}/>
<TextInput label={'Password'}/>
<input type='button' className='submit' onClick={() => check_login_info()} value='Log In'/>
<div className='bottom_text'>
New to Product? <Link className='sign-up' to='/signup'>Sign Up</Link>
</div>
</div>
</div>
)
};
export default Login;
Login.css
.login-card {
background-color: white;
border-radius: 20px;
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 90%;
width: 90%;
padding: 0px;
justify-content: center;
align-items: center;
display:flex;
}
@media (max-width: 800px) {
/* CSS that should be displayed if width is equal to or less than 800px goes here */
.login-card {
flex-direction: column-reverse;
}
}
@media (min-width:800px) {
.login-card {
flex-direction: row;
}
}
/* Uncomment for card-style background image */
.login-card-image {
background-image: url('../images/login-background-3.jpg');
height: 100%;
width: 100%;
background-size: cover;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
/* border-radius: 20px; */
}
.login-contents {
display: flex;
padding: 10%;
width: 50%;
flex-direction: column;
/* background-color: red; */
}
@media (min-width:800px) {
.login-contents-header {
margin: 5%;
padding: 5%;
font-size: 30px;
height: 50%;
justify-content: center;
text-align: center;
}
}
@media (max-width:800px) {
.login-contents-header {
margin: 5%;
padding: 5%;
padding-bottom: 0px;
margin-bottom: 0px;
font-size: 20px;
height: 50%;
justify-content: center;
text-align: center;
}
}
.login-contents span {
padding-top: 40px;
}
/* CSS */
.submit {
align-items: center;
background-color: rgb(202, 225, 246);
border-radius: 12px;
box-shadow: transparent 0 0 0 3px,rgba(18, 18, 18, .1) 0 6px 20px;
box-sizing: border-box;
color: #121212;
cursor: pointer;
display: inline-flex;
flex: 1 1 auto;
font-family: Inter,sans-serif;
font-size: 1.2rem;
font-weight: 700;
justify-content: center;
line-height: 1;
margin: 10%;
margin-left: 25%;
outline: none;
padding: 15px;
text-align: center;
text-decoration: none;
transition: box-shadow .2s,-webkit-box-shadow .2s;
width: 50%;
white-space: nowrap;
border: 0;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
}
.submit:hover {
box-shadow: rgb(148, 179, 206) 0 0 0 3px, transparent 0 0 0 0;
}
.submit {
color: black;
text-decoration: none;
}
.bottom_text {
/* background-color: red; */
justify-content: center;
text-align: center;
}
.sign-up {
color: rgb(26, 158, 202);
text-decoration: none;
}
.error {
color: red;
font-size: 20px;
margin: 0px;
margin-top: 30px;
}
Signup.js
import '../components-css/Signup.css'
import Logo from '../components-js/Logo.js';
import TextInput from './TextInput.js';
import Back from '../images/arrow.png';
import {Link} from 'react-router-dom'
function Signup() {
return (
<div className='signup'>
<div className='signup-form-container'>
<div className='signup-form-padding'>
<div className='back'>
<Link to='/'>
<img src={Back} alt='backarrow' width='100%' height='80%'/>
</Link>
</div>
<div className='logo'>
<Logo/>
</div>
<div className='header'>
Create Account
</div>
<div className='form-container'>
<form className='form'>
<TextInput label={'First Name'}/>
<TextInput label={'Last Name'}/>
<TextInput label={'Email'}/>
<TextInput label={'Phone Number'}/>
<TextInput label={'Password'}/>
<TextInput label={'Confirm Password'}/>
</form>
<input className='submit' type='submit' value='Submit'></input>
</div>
</div>
</div>
</div>
);
}
export default Signup;
Signup.css
.signup {
justify-content: center;
height: 100vh;
/* background-color: red; */
position:absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
.signup-form-container {
height: 85%;
width: 40%;
margin: auto;
margin-top: 3%;
margin-bottom: 5%;
background-color: white;
border-radius: 50px;
overflow: auto;
}
.signup-form-padding {
height: 90%;
width: 90%;
margin: auto;
margin-top: 5%;
/* background-color: red; */
justify-content: center;
position: relative;
}
.back {
position: absolute;
top: 0px;
}
.back img{
width: 20px;
height: 20px;
}
.logo {
height: 11%;
width: 70%;
margin:auto;
display:flex;
flex-direction: row;
/* background-color: red; */
}
.header {
text-align: center;
font-size: 20px;
margin-bottom: 2%;
}
.form {
width: 60%;
justify-content: center;
margin-bottom: -50px;
}
.form input {
margin-top: 0px;
margin-left: 0px;
}
.submit {
}
When rendering my Signup page, it somehow uses the css from Login.css to show the Submit button. Upon further inspection, it appears the browser is loading ALL of my css files, one by one (in the on the screenshot below). I noticed this by looking at the inspector on the browser itself:
What is happening? I'm not sure why it seems to render all of the styles at once.
CodePudding user response:
This is expected. ESM imports, including CSS via things like webpack are static imports. They will be loaded as soon as the bundle loads, and it doesn't matter if the component you imported it in is loaded or not. Its included because somewhere in your code you import login, as well as signup -- so the CSS imports are resolved in one go.
Css-in-js libs like styled-components
do only load the styles if the relevant component is rendered. Static CSS importing is not really css-in-js. Those are globally provided. You might consider those solutions if you want better scoping of styles.
You could also consider CSS modules.
CodePudding user response:
One very easy way to solve this would be to start using Sass and wrap all your CSS for a given page in class names and then within your pages, apply the class name to the outermost div
.
To enable Sass support:
npm install sass --save-dev
Then rename your .css
files to .scss
and update imports.
Login.scss
.login-card {
// all styes specific to login page go here
}
Signup.scss
.signup {
// all styles specific to signup page go here
}