React: Child Component div is also applied to sibling. Why? - javascript

This is the render method of one of my components:
render() {
return (
<div className="left col-xs-12 col-md-6">
<Dropdown show={this.state.showDropdown}/>
{this.props.children}
</div>
);
}
It's just a div with a full screen dropdown menu, and some children. When showDropdown===true, the dropdown menu is shown. Now in one of the pages in which this component is used, the immediate child has a some issues with formatting, so I included a padding: 50px. This solved the issue. But now my Dropdown component also gets the padding of 50px, which moves my Dropdown Menu Items down and ruins the formatting of the Dropdown - but I don't know why? Is this normal behaviour?
CSS of the parent:
.left {
display: flex;
justify-content: center;
align-items: center;
// background-color: MediumSpringGreen;
background-color: $color_left;
height: auto;
min-height: 100vh;
z-index: 1;
#include media-breakpoint-up(md) {
height: 100vh;
}
}
Code of child
render() {
return (
<div className="row">
<Loader show={this.state.loading} />
<Left>
<div className="about_padding">
<p className="red big-box-text-two">Text text text</p>
<a className="menu-link statementbox" id="menu-statement" href="./pdf/statement.pdf" download="statement.pdf">
<p className="menu-link-text">our statement</p>
<img className="img-fluid download-img" src={imgDownload} alt="download"></img>
</a>
</div>
</Left>
}
CSS of the child:
.statementbox {
margin-top: 20px !important;
}
.about_padding {
padding-left: 15%;
padding-right: 15%;
//I was trying to add padding-top here, but it also pushes down my Dropdown
#include media-breakpoint-down(xs) {
padding-left: 10%;
padding-right: 10%;
}
}
Code of the Dropdown:
const Dropdown = ({show}) =>
<div className="dropdown"
style={{
visibility: show ? "visible" : "hidden",
opacity: show ? 1 : 0
}}>
<Link to="/">Home</Link>
<Link to="/menus/">Menus</Link>
<Link to="/about/">About us</Link>
<Link to="/contact/">Contact</Link>
</div>
CSS of the Dropdown:
.dropdown {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: 40px;
background-color: #FFD826;
position: absolute;
height: 100%;
width: 100%;
z-index: 2;
a {
color: #f42528 !important;
}
}

Related

Collapsible side menu with CSS flexbox

I'm trying to create a collapsible sidebar on the left.
I want to set it up real simple: 2 columns which contains of 2 flex boxes, and when a button is pushed: the left flex box increases in width and the tight flexbox just moves with. When the button is clicked again, the flexbox on the left decreases again in side, back to the first state where the menu cannot be seen.
My problem is that I don't know how a click event of a button can control the width size of the flexbox.
What I have now is this:
html
<div>
<button
onClick={handleViewMenu}??
style={{ height: "30px", width: "30px" }}>
</button>
</div>
<div className='container'>
<div className='container-left'>
Left
</div>
<div className='container-right'>
right
</div>
</div>
scss
.container { width: 100vw;
height: 100vh;
display: flex;
&-left {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
// flex: 0.3 0 auto;
// background-color: aqua;
} &-right {
flex: 1 0 auto;
}
}
I just don't know how to deal with the onClick event (where I put the ??. I work in React so I found different things like:
const [sideMenuOpen, setMenuOpen] = useState(false);
const handleViewMenu = () => {
setMenuOpen(!sideMenuOpen);
};
But it should be pretty easy to handle this I think, but I can't find a solution..
Here's a solution that doesn't need javascript by using the :has() pseudo class. Just set the width of the side bar when the checkbox is clicked and if you're using normal flexbox the right hand one will automatically shift to suit. See below. Any questions drop me a comment.
/* essential to add this as there's a default 8px margin */
body {
margin: 0;
}
/* this is also essential to avoid a world of width-based pain */
* {
box-sizing: border-box;
}
/* Just making things pretty here */
nav {
display: flex;
width: 100%;
gap: 1rem;
padding: 0.5rem 1rem;
background-color: purple;
color: white;
}
/*the menu button is basically a hidden check box, we use label to style it as a button */
.menubutton>input {
display: none;
}
/*these toggles the display of the menu button, it works because the label after the input element */
.menubutton>input:checked+label .not-active {
display: none;
}
.menubutton>input:not(:checked)+label .active {
display: none;
}
.container {
display: flex;
width: 100%;
}
.container-left {
background-color: plum;
height: 50vh;
padding: 0.5rem 0.5rem;
border: 1px solid transparent;
width: 3rem;
transition: width 300ms;
}
/* this is the bit that styles the width of the sidebar when the checkbox is checked. */
body:has(.menubutton > input:checked) .container-left {
width: 10rem;
}
/* just style the right box for visibility */
.container-right {
border: 1px solid lightgray;
height: 50vh;
flex-grow: 1;
padding: 0.5rem 0.5rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<nav>
<div class='menubutton'><input type='checkbox' id='menubuttoninput'><label for='menubuttoninput'><i class="fa-solid fa-bars not-active"></i><i class="fa-solid fa-xmark active"></i></label></div>
This is a navbar!
</nav>
</div>
<div class='container'>
<div class='container-left'>
Left
</div>
<div class='container-right'>
right
</div>
</div>
If you do need a javascript solution then attach a listener to the checkbox input element and toggle the sidebar class to change the width as below:
window.onload = () => {
document.querySelector('.menubutton input').addEventListener('change', (e) => {
const sidebar = document.querySelector('.container-left');
if (e.target.checked) {
sidebar.classList.add('sidebar-active');
} else {
sidebar.classList.remove('sidebar-active');
}
});
}
/* essential to add this as there's a default 8px margin */
body {
margin: 0;
}
/* this is also essential to avoid a world of width-based pain */
* {
box-sizing: border-box;
}
/* Just making things pretty here */
nav {
display: flex;
width: 100%;
gap: 1rem;
padding: 0.5rem 1rem;
background-color: cornflowerblue;
color: white;
}
/*the menu button is basically a hidden check box, we use label to style it as a button */
.menubutton>input {
display: none;
}
/*these toggles the display of the menu button, it works because the label after the input element */
.menubutton>input:checked+label .not-active {
display: none;
}
.menubutton>input:not(:checked)+label .active {
display: none;
}
.container {
display: flex;
width: 100%;
}
.container-left {
background-color: lightblue;
height: 50vh;
padding: 0.5rem 0.5rem;
border: 1px solid transparent;
width: 3rem;
transition: width 300ms;
}
/* this is the bit that styles the width of the sidebar when the checkbox is checked. We just add this using javascript*/
.sidebar-active {
width: 10rem;
}
/* just style the right box for visibility */
.container-right {
border: 1px solid lightgray;
height: 50vh;
flex-grow: 1;
padding: 0.5rem 0.5rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<nav>
<div class='menubutton'><input type='checkbox' id='menubuttoninput'><label for='menubuttoninput'><i class="fa-solid fa-bars not-active"></i><i class="fa-solid fa-xmark active"></i></label></div>
This is a navbar!
</nav>
</div>
<div class='container'>
<div class='container-left'>
Left
</div>
<div class='container-right'>
right
</div>
</div>

How do I change the size of the parent div without affecting the children nodes displayed?

I am developing a dashboard application where the user can view information regarding cryptocurrencies, I have fetched the information using coingecko's API, now I want to render the information in a particular place on the page, here is a screenshot of the project I am working on
Here is the React code and the CSS for this part of the page that is being rendered
import React from 'react'
import { Typography } from 'antd'
import "./PriceCard.css"
const { Text, Title } = Typography
const PriceCards = ({ cryptoProps }) => {
if (!cryptoProps[0]){
return <></>
}
return (
<div className='priceCard'>
<div className="cryptoInfo">
<img src={cryptoProps[0].image}/>
</div>
<div className="cryptoInfo">
<Title level={3}>All Time High</Title >
<Text strong={true}>$ {cryptoProps[0].ath}</Text>
</div>
<div className="cryptoInfo">
<Title level={3}>Market Cap</Title >
<Text strong={true}>$ {cryptoProps[0].market_cap}</Text>
</div>
<div className="cryptoInfo">
<Title level={3}>Price Change (24 hours)</Title >
<Text strong={true}>{cryptoProps[0].price_change_percentage_24h} %</Text>
</div>
</div>
)
}
export default PriceCards
.priceCard {
width: 100%;
height: 100%;
margin-top: 10vh;
position: absolute;
right: 10;
padding-right: 80em;
border-style: dashed;
}
.cryptoInfo {
box-sizing: border-box;
padding: 10px;
float: left;
width: 35%;
height: 35%;
text-align: center;
}
As you can see the parent div, with the className 'priceCard' has a size that spans the whole page, but I want it to be sized where its just on the top left, where all the information is being presented, but the issue is, once I try to meddle around with the CSS, it messes up the whole page and the information being presented.I still want the information being presented in a grid-like fashion how it is done right now, without anything being moved if I change any CSS to the 'priceCard' div.
You use float that's why the boxes move. Here I have added grid:
.priceCard {
width: 50%;
height: 100%;
margin-top: 10vh;
position: absolute;
right: 10;
/*padding-right: 80em;*/
border-style: dashed;
display:grid;
grid-template-columns: 1fr 1fr
}
.cryptoInfo {
box-sizing: border-box;
padding: 10px;
text-align: center;
}
<div class='priceCard'>
<div class="cryptoInfo">
<img src={cryptoProps[0].image} alt="image"/>
</div>
<div class="cryptoInfo">
All Time High
</div>
<div class="cryptoInfo">
Market Cap
</div>
<div class="cryptoInfo">
Price Change (24 hours)
</div>
</div>
You can use display:grid; to have fixed grid to display the content.
.priceCard {
width: 50%;
height: 100%;
margin-top: 10vh;
position: absolute;
border-style: dashed;
display:grid;
grid-template-columns: 1fr 1fr;
}
.cryptoInfo {
box-sizing: border-box;
padding: 10px;
text-align: center;
}
<div class='priceCard'>
<div class="cryptoInfo">
<img src={cryptoProps[0].image} alt="image"/>
</div>
<div class="cryptoInfo">
All Time High
</div>
<div class="cryptoInfo">
Market Cap
</div>
<div class="cryptoInfo">
Price Change (24 hours)
</div>
</div>

Padding of Sliders affect the Fixed Top Bar

I have a HTML section of Top Bar which is fixed to view port. And another section of slider. These two 2 section are not totally related to each other as they are the same level in DOM tree. But when I edit the default padding of div.col of Slider, it affect the TopBar. It seems top bar is pulled to bottom and right side when padding of Section edited. I have tried my ways but no way help. Could you please advise any suggestion? Thank you so much. You can view live demo at: https://vanminhquangtri.github.io/football-fashion/
The Top Slide:
import React from 'react';
import {NavLink} from "react-router-dom";
import TinySlider from "tiny-slider-react"
const settings = {
items: 1,
nav: false,
autoplay: true
}
const TopSlide = () => {
return (
<section className="top-slide">
<div className="container-fluid">
<div className="row">
<div className="col">
<div className="wrap">
<TinySlider settings={settings}>
<div className="slide-item item-1">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Always update the latest</h5>
<NavLink
to="/best-sales"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
<div className="slide-item item-2">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Bring you the champion's fashion</h5>
<NavLink
to="/champion"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
<div className="slide-item item-3">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Top-five leagues in the world</h5>
<NavLink
to="/all-fashion"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
</TinySlider>
</div>
</div>
</div>
</div>
</section>
);
};
export default TopSlide;
The TopBar:
// top bar of web page
import React from 'react';
import {NavLink} from "react-router-dom";
import Logo from "../../Assets/images/section-top-bar/ball.png";
import Leagues from "../../Assets/images/section-top-bar/leagues.jpg";
import HotDeal from "../../Assets/images/section-top-bar/hotdeal.png";
const TopBar = () => {
return (
<section className="top-bar">
<div className="container-fluid">
<div className="row">
{/* ball icon */}
<div className="col-3 ball-icon">
<div className="wrap">
<NavLink
to="/"
exact={true}
>
<img
src={Logo}
alt="ball-icon"
/>
</NavLink>
</div>
</div>
{/* icons of top-5 leagues */}
<div className="col-6 leagues-icon">
<div className="wrap">
<NavLink
to="/most-concerned"
exact={true}
>
<img
src={Leagues}
alt="leagues-icon"
/>
</NavLink>
</div>
</div>
{/* hot deals icon */}
<div className="col-3 top-bar-hot-deals">
<div className="wrap">
<NavLink
to="/hot-deal"
exact={true}
>
<img
src={HotDeal}
alt="leagues-icon"
/>
</NavLink>
</div>
</div>
</div>
</div>
</section>
);
};
export default TopBar;
CSS:
/*--- top bar ---*/
.top-bar {
z-index: 2000;
position: fixed;
left: 0;
bottom: 0;
right: 0;
width: 100%;
border-top: 1px solid rgb(235, 235, 235);
background: white;
.container-fluid {
.row {
.wrap {
width: 100%;
a {
display: block;
width: 100%;
}
img {
height: 30px;
}
}
.col-3.ball-icon {
display: flex;
align-items: center;
justify-content: flex-start;
padding-left: 5px;
img {
width: 30px;
}
}
.col-6.leagues-icon {
text-align: center;
img {
height: 35px;
}
}
.col-3.top-bar-hot-deals {
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 5px;
img {
width: 100%;
}
}
}
}
}
/*--- end top bar ---*/
Slider:
/*--- top slide ---*/
.top-slide {
margin-top: 10px;
.container-fluid {
.row {
.col {
padding: 0; PROBLEM HERE, IF REMOVE THIS TOP BAR WILL BE NOT AFFECTED, BUT I NEED TO KEEP THIS SO THAT IT LOOKS BETTER IN MOBILE
.wrap {
.tns-outer {
> button {
display: none;
}
position: relative;
/* next and back button of slide */
.tns-controls {
z-index: 100;
position: absolute;
top: 40%;
width: 100%;
padding: 0 5px;
display: flex;
justify-content: space-between;
button {
border: none;
outline: none;
background: transparent;
color: transparent;
width: 20px;
height: 20px;
background : {
size: cover;
position: center;
repeat: no-repeat;
}
}
button[data-controls=prev] {
background-image: url("../src/Assets/images/section-top-slide/previous-3.png")
}
button[data-controls=next] {
background-image: url("../src/Assets/images/section-top-slide/next-3.png")
}
}
.tns-ovh {
.tns-inner {
.tns-slider {
/* each item of slider is a div named slide-item */
.slide-item {
.background-image {
height: 150px;
background: {
position: center 0;
repeat: no-repeat;
size: cover;
}
}
.slide-caption {
text-align: center;
.title {
font-weight: bold;
font-size: 16px;
margin-bottom: 0;
}
.link {
color: white;
background: $color-red;
display: inline-block;
padding: 2px 5px;
border-radius: 3px;
font-size: 14px;
font-weight: bold;
}
}
}
.slide-item.item-1 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/tot.webp")
}
}
.slide-item.item-2 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/arsenal.jpg")
}
.title {
text-shadow: 1px 1px 3px $color-red;
}
}
.slide-item.item-3 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/mc.jpg")
}
.title {
text-shadow: 1px 1px 3px #5fa5e3;
}
}
}
}
}
}
}
}
}
}
}
/*--- end top slide ---*/

Flexbox row is not scrolling when I scroll the mouse

I have built a Netflix row using Flexbox. I can scroll through the row only if I press Shift + mouse scroll and when I use the developer tool.
But I want to be able to scroll/slide through the row when I do mouseover/mouse scroll. Like if mouseover on the row, I'll be able to slide the row/scroll through it. So how can I achieve that?
Here is my .jsx file:
<div className="row">
{ /* Title */ }
<h2>{title}</h2>
<div className="row-posters">
{ /* Several row posters */ }
{movies.map((movie) => {
return (
<img
key={movie.id}
onClick={() => handleClick(movie)}
src={`${baseUrl}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
className={`row-poster ${isLargeRow && "row-posterLarge"}`}
/>
);
})}
</div>
{trailerUrl && <Youtube videoId={trailerUrl} opts={opts} />}
</div>;
Here is my CSS:
.row{
margin-left: 20px;
color: #FFF;
}
.row-posters{
display: flex;
flex: row;
overflow-y: hidden;
overflow-x: auto;
padding: 20px;
}
.row-posters::-webkit-scrollbar{
display: none;
}
.row-poster{
object-fit: contain;
width: 100%;
max-height: 100px;
transition: transform 450ms;
margin-right: 10px;
cursor: pointer;
counter-increment: row-poster;
}
.row-poster:hover{
transform: scale(1.08);
}
.row-posterLarge{
max-height: 250px;
}
.row-posterLarge:hover{
transform: scale(1.09);
opacity: 1;
}
Here is an image of my row.
You can't scroll on a flexible element. One way is wrap 'row-posters' inside 'row-posters-container' element and give styles to that element with
<div className="row">
{/* title */}
<h2>{title}</h2>
<div className="row-posters-container">
<div className="row-posters">
{/* several row posters */}
...
</div>
</div>
</div>
.row-posters-container {
max-width: 100%;
overflow-x: auto;
}

Dropdown menu - z-index stacking issue

My team and I are having trouble stacking a Dropdown component on our page. Essentially, we want the Dropdown to slide down underneath the top-nav when the button is clicked, but as it slides down, it should be positioned above everything else: the sub-nav and the content below.
Currently, the Dropdown is positioned as absolute and the animation is performed with a transform: translateY(). We've tried positioning the elements outside of it as relative (the outer <ul>, <nav>, and <div id="top-nav"> elements that are bolded) with a higher z-index to ensure the dropdown stays below it, but so far it hasn't worked.
We're also not able to modify any of the CSS or structure of the div#content below, but we do have flexibility as to where we can place the Dropdown structurally in the #header.
EDIT: Tried my best to recreate the scenario with JSFiddle here: https://jsfiddle.net/4zaas4sq/
Here's roughly what our markdown looks like:
<body>
<div id="header">
<div>
**<div id="top-nav">**
<div>
**<nav>**
<ul></ul>
**<ul>**
<li>
<DROPDOWN>
<button onClick={toggleDropdown}>Log In</button>
<div className={(this.state.show && 'show})>
<ul></ul>
</div>
...
</DROPDOWN>
</li>
<li></li>
</ul>
</nav>
</div>
</div>
<div id="sub-nav">
...
</div>
</div>
</div>
<div id="content">
</div>
</body>
Here's a wireframe depicting the final state of the dropdown.
Any help or suggestions would be appreciated!
I used max-height property.I didn't change a lot of things in your code.In JS code you will see main changes.Let me know if this solution is what you want.Thanks :)
In html code add class="hideItem" in the divider with id="dropdown" like this:
<div id="dropdown" class="hideItem">
JS code
$(document).ready(function() {
$('#dropdown-button').click(function() {
if( $("#dropdown").hasClass( 'hideItem' )){
$( "#dropdown" ).css( 'max-height' , '100%' );
$("#dropdown").removeClass( 'hideItem' );
$("#dropdown").addClass( 'showItem' );
}else{
$( "#dropdown" ).css( 'max-height' , '0' );
$("#dropdown").addClass( 'hideItem' );
$("#dropdown").removeClass( 'showItem' );
}
});
});
css code
html, body {
height: 100%;
}
#top-nav {
background-color: mediumpurple;
width: 100%;
}
.nav {
display: flex;
justify-content: space-between;
}
.inner-left-nav {
list-style: none;
display: flex;
}
.inner-left-nav li {
padding: 5px;
border: 1px solid black;
}
.inner-right-nav {
display: flex;
list-style: none;
margin: 0;
}
.inner-right-nav li {
align-items: center;
padding: 0 5px;
}
.dropdown-container {
display: flex;
align-items: center;
height: 100%;
}
#dropdown {
position: absolute;
top: 70px;
right: 100px;
max-height: 0;
overflow-y: hidden;
transition: max-height 1s ease-in-out;
background-color: mediumseagreen;
}
#dropdown.show {
visibility: visible;
transform: translateY(0%);
transition: visibility 0s, transform 0.3s;
}
#dropdown-button {
border: 1px solid black;
background: transparent;
padding: 0 20px;
cursor: pointer;
}
.dropdown-list {
padding: 0;
list-style: none;
}
#sub-nav {
display: flex;
justify-content: space-between;
background-color: grey;
}
#content {
background-color: azure;
width: 100%;
height: 100%;
}

Categories