Why does my page width only stretch to 100% with "fit-content"? - javascript

I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:
html, body{
background-color: rgb(167, 72, 72);
height: 100%;
min-width: 100%;
}
I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink
I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.
Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.
Here is the JSX I have for reference:
import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";
const Header = () => {
const texts = [
'ORDERS OF $5K SHIP FREE',
'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
];
let currentTextIndex = 0;
setInterval(() => {
const shippingDealsText = document.querySelector('.shipping-deals-text');
shippingDealsText.classList.add('out');
setTimeout(() => {
shippingDealsText.textContent = texts[currentTextIndex];
shippingDealsText.classList.remove('out');
currentTextIndex = (currentTextIndex + 1) % texts.length;
}, 1000);
}, 5000);
return (
<div className="header">
<div className="header-top">
<div className="top-logo">
<h5 className='small-logo'>LEVIATHAN</h5>
</div>
<div className="space"></div>
<div className="link-container">
<div className="link-wrap">
Gift Cards
</div>
<div className="link-wrap">
Contact Us
</div>
<div className="link-wrap">
Order Status
</div>
<div className="link-wrap">
Live Chat
</div>
</div>
</div>
<div className="header-middle">
<div className="middle-logo">
<h5 className='big-logo'>LEVIATHAN</h5>
</div>
<div className="search-container">
<div className="search-wrapper">
<input
type="text"
id="search-bar"
placeholder="Search"
className='search'
/>
<div className="search-icon-wrapper">
<SearchIcon className='search-icon'/>
</div>
</div>
</div>
<div className="shipping-deals-container">
<div className="button-container">
<div className="shipping-deals-button">
<span className="deals-text">DAILY SHIPPING DEALS </span>
</div>
</div>
<div className="text-container">
<div className="text-slideshow">
<p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
</div>
</div>
</div>
<div className="icons-right">
<Profile className='login-pic'/>
<span>Log In</span>
<Cart className='shopping-cart'/>
</div>
</div>
<div className="header-bottom">
<div className="nav-bar">
<ul className='navigation'>
<li className='menu-items'>
<a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
<a href="/" className='button'>Equipment for Crossfit</a>
<a href="/" className='button'>New Gear</a>
<a href="/" className='button'>Barbells</a>
<a href="/" className='button'>Plates</a>
<a href="/" className='button'>Rigs and Racks</a>
<a href="/" className='button'>Shoes</a>
<a href="/" className='button'>Apparel</a>
<a href="/" className='button'>3 Ships Free</a>
<a href="/" className='button'>Zeus</a>
<a href="/" className='button drop-down'>The Index</a>
</li>
</ul>
</div>
</div>
</div>
)
}
export default Header
Here is the styling I am currently applying:
.header {
min-width: 100%;
margin: 0;
padding: 0;
}
.header-top {
background-color: white;
display: flex;
height: 2.5rem;
width: 100%;
}
.top-logo {
position: relative;
margin-left: 3rem;
}
.space {
flex-grow: 1;
}
.small-logo {
padding-top: 0.5em;
position: relative;
font-size: larger;
color: rgb(133, 133, 133)
}
.link-container {
display: flex;
/*border: 1px solid red;*/
margin-right: 3rem;
}
.link-wrap {
/*border: 1px solid green;*/
font-size: 14px;
padding-left: 1rem;
padding-top: 0.75rem;
}
.link-wrap a {
text-decoration: none;
color:#666666;
cursor: pointer;
}
/* Large section of header, black background */
.header-middle {
background-color: black;
height: 7rem;
display: flex;
}
/* Big LEVIATHAN text */
.middle-logo {
/*border: 1px solid red;*/
position: relative;
margin-left: 3rem;
display: flex;
justify-content: center;
align-items: center;
cursor: co;
}
.big-logo {
font-size: 48px;
/*padding-top: 2rem;*/
position: relative;
color: white;
}
.big-logo:hover {
color: rgb(210, 0, 0);
}
.search-container {
position: relative;
width: 40%;
display: flex;
flex-basis: 60%;
margin-left: 3rem;
align-items: center;
justify-content: center;
}
/*This is what has the appearance of the search bar*/
.search-wrapper {
min-width:100%;
height: 35%;
position: relative;
background-color: white;
display: flex;
flex-basis: 50%;
}
.search-icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
}
.search-icon {
color: black;
font-size: 20px;
}
/*This is the actual search bar tucked inside*/
.search {
width: 100%;
height: 100%;
border: none;
outline: none;
margin-left: 1em;
font-size: 17px;
}
.search::placeholder {
color:rgb(94, 94, 94);
}
/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
width: 18em;
margin-left: 2.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
/*border: 2px solid rgb(136, 77, 255);*/
}
.shipping-deals-button {
width: 65%;
height: 44%;
background-color: rgb(234, 2, 2);
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-top: 1.5em;
}
.button-container {
width: 100%;
height: 50%;
/*border: 2px solid magenta;*/
}
.deals-text {
color: white;
font-size: 12px;
position: relative;
text-align: center;
align-items: stretch;
width: 100%;
}
.text-container {
/*border: 2px solid rgb(20, 182, 11);*/
width: 100%;
height: 50%;
}
.text-slideshow {
color: white;
width: 100%;
height: 50%;
font-size: 12px;
}
.shipping-deals-text {
transition: opacity 1s;
opacity: 1;
font-size: 13px;
}
.out {
opacity: 0;
transition: opacity 1s;
}
.shipping-deals-text-red{
color: red;
}
.navigation {
display: flex;
align-items:flex-start;
height: 3rem;
}
.menu-items {
height: 100%;
margin-left: 1.5rem;
padding-right: 1.5rem;
display: flex;
align-items: flex-start;
flex: 1;
}
ul {
list-style-type: none;
background-color: #333333;
}
.button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
text-decoration: none;
color: white;
text-transform: uppercase;
white-space: nowrap;
padding: 1em;
font-weight: bold;
}
.button:hover {
color:rgb(210, 0, 0)
}
.red {
background-color: rgb(210, 0, 0);
}
.red:hover {
color: white;
}
.drop-icon {
font-size: 25px;
}
.icons-right {
height: 50%;
margin-top: 2em;
min-width: 10%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1rem;
}
.login-pic {
color: white;
font-size: 20px;
}
.shopping-cart {
color: white;
font-size: 20px;
margin-left: 1rem;
}
.icons-right span {
color: white;
margin-left: 0.5em;
}
#media (max-width: 1025px) {
.shipping-deals-container {
display: none;
}
.header-top {
display: none;
}
.header-middle {
height: 50%;
}
.search-wrapper {
border: 2px solid white;
height: 2rem;
}
.icons-right {
margin-bottom: 2rem;
}
}
I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for

With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.
The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;
Hope this helps.
On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.
It should look more like this ->
<ul>
<li>
Shop
</li>
<li>
Equipment for Crossfit
</li>
<li>
New Gear
</li>
<!-- ... -->
</ul>

Related

Why all the SCSS files are imported to every component? - ReactJs [duplicate]

This question already has answers here:
How to load different .css files on different components of a react application?
(4 answers)
Closed 6 months ago.
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.
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.
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
}

How can I change 2 column layout to a tabbed layout for tablet and mobile

Hi I am updating an old website for a Spanish Cafe. At the moment it uses a 2 column layout for desktop, then a smaller version for tablets and finally a tabbed layout for mobile users:
as this involves 3 layouts there is a lot of repetitive text. What I would like to do is have a responsive design changing from 2 column to tabbed through breakpoints.
Is this possible? I have googled everywhere but cannot find anything.
If anyone should wonder the same thing, here is how I managed to do it (just an example of code).
At the top I hide a div with 2 tabs by display:none; then I have a flex-container with 2 flex items, left is in Spanish and right in English.
Both display side by side until the viewport gets to 600px the the media-query hides all the english flex items and shows the tab div.
With a bit of javascript the user can toggle between Spanish and English
HTML
<br>
<div class="wrap">
<div class="tabh" style="margin:0 auto;">
<div id="esp" class="atab" onclick="func('a')">Español</div>
<div id="eng" class="atab" onclick="func2('b')">English</div>
</div>
<div class="flex-container">
<div class="flexitem spanish">Spanish</div>
<div class="flexitem english">English</div>
</div>
<div class="flex-container">
<div class="flexitem spanish">Spanish</div>
<div class="flexitem english">English</div>
</div>
<div class="flex-container">
<div class="flexitem spanish">Spanish</div>
<div class="flexitem english">English</div>
</div>
</div>
CSS
.wrap {
width: 900px;
max-width: 100%;
margin: 0 auto;
}
.flex-container {
width: 100%;
display: flex;
margin: 0 auto;
flex-direction: row;
justify-content: space-between;
font-family: Roboto;
font-weight: bolder;
color: white;
}
.flexitem {
text-align: left;
width: 50%;
padding: 0 15px;
}
.tabh {
width: 90%;
margin-left: auto;
margin-right: auto;
display: none;
text-align: center;
font-family: Roboto;
font-weight: bolder;
margin-bottom: 10px;
}
.atab {
width: 50%;
height: 25px;
display: table-cell;
border-radius: 10px;
cursor: pointer;
padding-top: 4px;
border: 1px solid black;
}
.spanish {
background-color: red;
height: 100px;
margin: 5px;
text-align: center;
}
.english {
background-color: blue;
height: 100px;
margin: 5px;
text-align: center;
}
#media only screen and (max-width: 600px) {
.english {
display: none;
width: 100%;
}
.spanish {
width: 100%;
}
.tabh {
display: flex;
}
.flex-container {
flex-direction: column;
}
}
#media only screen and (min-width: 601px) {
.spanish {
display: block !important;
width: 50%;
}
.english {
display: block;
width: 50%;
}
.tabh {
display: none;
}
}
javascript
function func(a) {
const esps = document.querySelectorAll('.spanish');
const engs = document.querySelectorAll('.english');
esps.forEach(esp => {
esp.style.display = "block";
});
engs.forEach(eng => {
eng.style.display = "none";
});
}
function func2(b) {
const esps = document.querySelectorAll('.spanish');
const engs = document.querySelectorAll('.english');
esps.forEach(esp => {
esp.style.display = "none";
});
engs.forEach(eng => {
eng.style.display = "block";
});
}
A working example is here jsfiddle
I hope this helps someone.

disable left or right arrow at the last item

Just made a simple div slider with navigation arrows. The div slider works just fine, except, I want some sort of CSS styling to be applied to the arrows.
That is, when a user clicks the left or right arrow, up to the last item, apply CSS styling telling the user they've reached the end of the slider.
let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')
let container = document.getElementById('slider')
buttonLeft.addEventListener('click', function() {
container.scrollLeft -= 90
})
buttonRight.addEventListener('click', function() {
container.scrollLeft += 90
})
body {
background-color: #555;
height: 100vh;
display: grid;
align-items: center;
justify-items: center;
font-family: 'Helvetica';
}
div#slide_wrapper {
width: 440px;
display: flex;
justify-content: space-between;
height: fit-content;
}
div#slider {
width: 350px;
display: flex;
height: fit-content;
flex-wrap: nowrap;
overflow: hidden;
}
div.thumbnail {
min-width: 80px;
min-height: 80px;
cursor: pointer;
display: grid;
place-items: center;
font-size: 30px;
}
div.thumbnail:not(:last-child) {
margin-right: 10px;
}
div.thumbnail:nth-child(1) {
background-color: darkturquoise;
}
div.thumbnail:nth-child(2) {
background-color: goldenrod;
}
div.thumbnail:nth-child(3) {
background-color: rebeccapurple;
}
div.thumbnail:nth-child(4) {
background-color: powderblue;
}
div.thumbnail:nth-child(5) {
background-color: firebrick;
}
div.thumbnail:nth-child(6) {
background-color: sienna;
}
div.thumbnail:nth-child(7) {
background-color: bisque;
}
div.thumbnail:nth-child(8) {
background-color: navy;
}
div#slide_wrapper>button {
height: fit-content;
align-self: center;
font-size: 24px;
font-weight: 800;
border: none;
outline: none;
}
div#slide_wrapper>button:hover {
cursor: pointer;
}
<div id="slide_wrapper">
<button id="slide_left" class="slide_arrow">❮</button>
<div id="slider">
<div class="thumbnail active">1</div>
<div class="thumbnail">2</div>
<div class="thumbnail">3</div>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<div class="thumbnail">6</div>
<div class="thumbnail">7</div>
<div class="thumbnail">8</div>
</div>
<button id="slide_right" class="slide_arrow">❯</button>
</div>
Simply check to see if you need to disable each button based on the position of the scroll. Then if there is a need to disable a button, add the disabled class to the button, otherwise remove it.
Future enhancements.
Remove the hardcoded 360 value for the scroll end. This should be calculated from the size of the carousel items and the width of the viewport.
Allow more than one carousel to work with the same code. This could be achieved by using a javascript class that would hold the elements inside an object, separate from other carousels.
See the demo:
let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')
let container = document.getElementById('slider')
let checkScroll = function() {
if (container.scrollLeft <= 0)
buttonLeft.classList.add("disabled");
else
buttonLeft.classList.remove("disabled");
if (container.scrollLeft >= 360)
buttonRight.classList.add("disabled");
else
buttonRight.classList.remove("disabled");
}
checkScroll();
buttonLeft.addEventListener('click', function() {
container.scrollLeft -= 90;
checkScroll();
})
buttonRight.addEventListener('click', function() {
container.scrollLeft += 90;
checkScroll();
})
body {
background-color: #555;
height: 100vh;
display: grid;
align-items: center;
justify-items: center;
font-family: 'Helvetica';
}
div#slide_wrapper {
width: 440px;
display: flex;
justify-content: space-between;
height: fit-content;
}
div#slider {
width: 350px;
display: flex;
height: fit-content;
flex-wrap: nowrap;
overflow: hidden;
}
div.thumbnail {
min-width: 80px;
min-height: 80px;
cursor: pointer;
display: grid;
place-items: center;
font-size: 30px;
}
div.thumbnail:not(:last-child) {
margin-right: 10px;
}
div.thumbnail:nth-child(1) {
background-color: darkturquoise;
}
div.thumbnail:nth-child(2) {
background-color: goldenrod;
}
div.thumbnail:nth-child(3) {
background-color: rebeccapurple;
}
div.thumbnail:nth-child(4) {
background-color: powderblue;
}
div.thumbnail:nth-child(5) {
background-color: firebrick;
}
div.thumbnail:nth-child(6) {
background-color: sienna;
}
div.thumbnail:nth-child(7) {
background-color: bisque;
}
div.thumbnail:nth-child(8) {
background-color: navy;
}
div#slide_wrapper>button {
height: fit-content;
align-self: center;
font-size: 24px;
font-weight: 800;
border: none;
outline: none;
}
div#slide_wrapper>button:hover {
cursor: pointer;
}
.slide_arrow.disabled {
opacity: 0.2;
cursor: auto !important;
}
<div id="slide_wrapper">
<button id="slide_left" class="slide_arrow">❮</button>
<div id="slider">
<div class="thumbnail active">1</div>
<div class="thumbnail">2</div>
<div class="thumbnail">3</div>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<div class="thumbnail">6</div>
<div class="thumbnail">7</div>
<div class="thumbnail">8</div>
</div>
<button id="slide_right" class="slide_arrow">❯</button>
</div>
a simple solution to this is to actually create a css class that defines the style of arrows when there are no more items and then just add/remove class based on current index of items

React.js Setting State Modifies Website scale

when my component re-renders itself after setState(); it seems to set the wrong scale for the page and all the content seems to fall off the side, it looks like the HTML and CSS has got the wrong screen size, and therefore the images, text, and boxes don't fit the screen, this isn't an issue with my CSS breakpoints or anything but I don't understand what I need to do since i've never seen this before
Before re-render:
after re-render:
MoviesHome.js
constructor(props){
super(props)
this.state = {
slideUpClass: ['movieFullTabContainer', 'movieFullTabContainerClosed'],
isOpen: 0,
};
handleMovieClick = () => {
if(this.state.isOpen === 0){
this.setState({isOpen: 1});
}else{
this.setState({isOpen: 0});
}
}
...
<div className='rowsContainer'>
<div className='rowContent'>
{this.state.Trending != null ? <MoviesRow clickHandler={this.handleMovieClick} name={'For You'} index={0} movies={this.state.Trending}/> : ''}
{this.state.Trending != null ? <MoviesRow clickHandler={this.handleMovieClick} name={'Trending'} index={1} movies={this.state.Trending}/> : ''}
</div>
</div>
<MovieSlideUp clickHandler={this.handleMovieClick} slideupClass={this.state.slideUpClass[this.state.isOpen]}/>
MoviesRow.js
<div key={Math.random(0, 1000)} onClick={() => this.props.clickHandler()} className='sliderItem'>
<img className='sliderImg' src={`https://image.tmdb.org/t/p/w1280/${this.props.movies[i].poster_path}`} alt=''></img>
<div className='movieOverlayContainer'>
<div className='movieOverlayContainerContent'>
<p className='movieTitle'>{this.props.movies[i].title}</p>
<p>{this.props.movies[i].release_date.substring(0,4)}</p>
</div>
</div>
</div>
MovieFullTab.js
import CircleSVG from './SVG/Circle-Solid.svg';
import StarSVG from './SVG/Star-Solid.svg';
import HeartSVG from './SVG/Heart-Solid.svg';
import PlaySVG from './SVG/Play-Solid.svg';
...
<div id={this.props.slideupClass}>
<div onClick={() => this.props.clickHandler()} id='fullscreenTabContainer'>
<div id='fullscreenSurroundingContainer'>
<div id='fullscreenContent'>
<div id='movieInfoContainer'>
<div id='movieImageContainer'>
<img src='https://image.tmdb.org/t/p/w1280/jTswp6KyDYKtvC52GbHagrZbGvD.jpg'></img>
</div>
<div id='movieFullInfoContainer'>
<p id='movieFullInfoTitle'>Luca</p>
<p className='movieFullInfoText'>15</p>
<p className='movieFullInfoText'>2021</p>
<div id='fullGenreContainer'>
<p>Adventure</p>
<img alt='' className='seperator-side' src={CircleSVG}></img>
<p id='secondGenre'>Comedy</p>
</div>
<div id='movieFullRatingsContainer'>
<img id='featuredStarIcon' alt='' src={StarSVG}></img>
<p>8.6</p>
</div>
<div id='fullMovieInfoOverviewContainer'>
<p>Luca and his best friend Alberto experience an unforgettable summer on the Italian Riviera.
But all the fun is threatened by a deeply-held secret: they are sea monsters from another
world just below the water’s surface</p>
</div>
<div id='movieFullInfoButtonsContainer'>
<div id='movieFullInfoLikeButton'>
<img alt='' src={HeartSVG}></img>
</div>
<div id='movieFullInfoPlayButton'>
<p>Watch</p>
<img alt='' src={PlaySVG}></img>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
MoviesRow.css
.rowTopContainer{
display: flex;
align-items: baseline;
}
.ArrowButtonImage{
filter: invert(65%) sepia(5%) saturate(170%) hue-rotate(169deg) brightness(84%) contrast(82%);
}
.flippedArrow{
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
.buttonSlideContainer{
display: flex;
margin-left: auto;
}
.ButtonSlide:first-child{
margin-right: 35px;
}
.ButtonSlide{
width: 30px;
height: 25px;
cursor: pointer;
}
.movieRowTitleContainer{
margin-right: 20px;
}
.movieRowTitle{
color: white;
font-family: Bold;
font-size: 23px;
margin-bottom: 25px;
}
.viewAllButtonContainer {
cursor: pointer;
}
.viewAllButtonContainer:hover p {
text-decoration: underline;
}
.viewAllButtonContainer p {
color: white;
font-size: 0.9em;
}
.moviesRowSliderContainer{
display: flex;
overflow-x: hidden;
overflow: hidden;
width: 100%;
scroll-behavior: smooth;
}
.sliderItemContent:hover .movieOverlayContainer{
opacity: 1;
background-color: rgba(0, 0, 0, 0.61);
}
.sliderImg{
width: 100%;
height: 100%;
border-radius: 5px;
object-fit: cover;
}
.movieOverlayContainerContent{
position: relative;
top: 0;
left: 0;
text-align: center;
justify-content: flex-start;
display: flex;
flex-direction: column;
height: 90%;
width: 100%;
}
.movieOverlayContainerContent p:nth-child(2){
font-size: 1vw;
}
.movieTitle{
font-size: 1.4vw;
width: 80%;
margin-bottom: 5px;
margin: 0 auto;
margin-top: 5px;
font-family: Bold;
}
.movieShortInfoContainer{
margin-top: auto;
}
.movieShortInfoContent{
justify-content: center;
display: flex;
text-align: center;
margin-top: auto;
}
.movieShortInfoContent p:not(:first-child) {
/* margin-left: 15px; */
font-size: 0.9vw;
}
.movieShortInfoContent p:nth-child(3){
margin-left: 0;
}
.movieShortInfoContent p:nth-child(2){
margin-right: 15px;
}
.movieStarIcon{
height: 15px;
filter: invert(68%) sepia(95%) saturate(406%) hue-rotate(359deg) brightness(104%) contrast(88%);
}
.userRatingsContainer{
display: flex;
align-items: center;
}
.movieOverlayContainer {
position: absolute;
top: 0;
left: 0;
width: inherit;
height: inherit;
background-color: rgba(0, 0, 0, 0);
border-radius: 5px;
opacity: 0;
color: white;
transition: all 0.1s ease;
}
.sliderItem{
width: 19%;
height: auto;
flex:none;
position: relative;
}
.sliderItemContent{
height: 100%;
width: 80%;
cursor: pointer;
}
#media only screen and (max-width: 1400px) {
.sliderItem{
width: 18%;
}
}
#media only screen and (max-width: 650px) {
.sliderItem{
width: 38%;
}
.movieOverlayContainerContent p:nth-child(2){
font-size: 1.8vw;
}
}
#media only screen and (max-width: 550px) {
.movieTitle{
font-size: 3vw;
}
}
I Hope the code helps :)
It was simply the display: flex; container pushing the container, props to Drew Reese for helping resolve the issue... Thanks :)

Spacing between images

I have 3 images side-by-side, I would like to know how to get some spacing between them. I have tried everything, margins, padding and I don't know what to do.
.content1 {
background-image: url("http://www.thefreeloves.com/prototype/test/wp-content/uploads/2014/02/album-title.jpg");
color: white;
text-align: center;
width: 100%;
height: 20%;
display: block;
float: left;
}
.text1 {
font-family: "Goudy Old Style", Optima, sans-serif;
font-size: 40px;
margin-bottom: 0;
margin-top: 45px;
}
.text2 {
font-size: 30px;
color: #6CB9D9;
}
.album1 {
float: left;
width: 31%;
text-align: center;
}
.album2 {
display: inline-block;
width: 31%;
text-align: center;
}
.album3 {
float: right;
width: 31%;
text-align: center;
}
.album {
width: 100%;
overflow: hidden;
background-color: #191919;
}
<div class="content1">
<h3 class="text1">Our Latest Album<span class="slash"> / </span><span class="text2">Fresh from the house of Music Club Band</span></h3>
</div>
<div class="album">
<div class="album1">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA9133-650x385.jpg" alt="album1">
</div>
<div class="album2">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA9099-650x385.jpg" alt="album2">
</div>
<div class="album3">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA0373-650x385.jpg" alt="album3" class="album4">
</div>
</div>
You set your wrapping div's to 31% but you didn't change the size of your images so they were flowing outside the wrappers. If you set Overflow: hidden; on your album1, album2 and album3 div's you'll see that your margins are working on the divs but you'll only see part of your images. if you set the imgs themselves to a width of 100% as below you'll see it works.
.content1 {
background-image: url("http://www.thefreeloves.com/prototype/test/wp-content/uploads/2014/02/album-title.jpg");
color: white;
text-align: center;
width: 100%;
height: 20%;
display: block;
float: left;
}
.text1 {
font-family: "Goudy Old Style", Optima, sans-serif;
font-size: 40px;
margin-bottom: 0;
margin-top: 45px;
}
.text2 {
font-size: 30px;
color: #6CB9D9;
}
.album1 {
float: left;
width: 31%;
text-align: center;
margin: 1%;
}
.album2 {
display: inline-block;
width: 31%;
text-align: center;
margin: 1%;
}
.album3 {
float: right;
width: 31%;
text-align: center;
margin: 1%;
}
.album {
width: 100%;
overflow: hidden;
background-color: #191919;
}
.album img { width: 100%; }
<div class="content1">
<h3 class="text1">Our Latest Album<span class="slash"> / </span><span class="text2">Fresh from the house of Music Club Band</span></h3>
</div>
<div class="album">
<div class="album1">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA9133-650x385.jpg" alt="album1">
</div>
<div class="album2">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA9099-650x385.jpg" alt="album2">
</div>
<div class="album3">
<img src="http://www.thefreeloves.com/prototype/test/wp-content/uploads/2015/02/FDA0373-650x385.jpg" alt="album3" class="album4">
</div>
</div>
In each div tag, just place the following style = "margin-right: 20px;". So for example, for the first image, change it ot this
div style = "margin-right: 20px;" class="album1">
You don't need to use float, you can simply set the display of the albums to inline-block, and set the text-align of their parent to center. Note that the three images there are too wide to be in one line, so you'll have to adjust that yourself.
.album1 img, .album2 img, .album3 img {
//set img width and height here
}
.album1 {
display: inline-block;
//add padding/margin here
}
.album2 {
display: inline-block;
//add padding/margin here
}
.album3 {
display: inline-block;
//add padding/margin here
}
.album {
width: 100%;
overflow: hidden;
background-color: #191919;
text-align:center;
}

Categories

Resources