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;
}
Related
Mapping return 4 elements of an array includes icon,title,description. Despite all have same content, one of them is bigger than others.
Here is the mapping function
<div className=" grid grid-cols-2 space-x-5 p-3 space-y-3 mt-16 justify-center">
{cards.map((element) => {
return (
<div className=" feature-card1 ">
<div className="content">
<div className="front">
// here is the card content
</div>
</div>
</div>
</div>
);
})}
`
Here is the CSS :
.feature-card1 {
background-color: transparent;
height: 320px;
perspective: 1000px;
}
.feature-card1:hover .content {
transform: rotateY(-180deg);
}
.feature-card1 .content {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.5s ease-in-out;
transform-style: preserve-3d;
}
I would be happy if you try to solve it, thanks.
On my personal portfolio, I have a "Projects" page where I display different projects using Bootstrap cards. I render them all in from my CardData.js file, then map the values to a ProjectCard component. I would like to have 3 cards per row with the set margins and spacing that I currently have. Currently, if I add more than 3 cards, it smushes the cards all together into one row.
Any help or feedback is appreciated!
Projects.js (Page component):
import '../../App.css'; // main css file //may need to change path
import './projects.css'; // projects css file
import { CardData } from './CardData.js'; // data import for card data
// TODO: Make cards go onto new row when more than three cards are displayed
class Projects extends Component {
render() {
return (
<div id="project-div">
<Navbar navId="navb" logoId="logo" logoText="qprice" logoClass="mr-auto" class="navbar bg-white navbar-expand-md sticky-top navbar-fixed-top shadow ml-auto" />
<h1 id="header-projects" className="font-weight-bold text-uppercase text-center ">Projects</h1>
<div id="card-div">
{CardData.map((item, index) => {
return (
<ProjectCard cardImg={item.cardImg} cardURL={item.cardURL} cardTitle={item.cardTitle} cardText={item.cardText} />
)
})}
</div>
</div>
)
}
}
Projects.css:
#project-div {
/*background-image: url("../../img/so-white.png");*/
background-color: transparent;
background-image: url("../../img/topography.png");
width: 100vw;
height: 100vh;
}
/* header text */
#header-projects {
margin-top: 50px;
margin-bottom: 50px;
color: #343a40;
}
/* nav links */
.nav a {
color: black;
}
/* div that holds cards */
#card-div {
display: flex;
width: 100%;
}
#portrait {
width: 300px;
display: inline;
border: 5px;
float: left;
margin-right: 15px;
}
.project-cards p {
font-family: "Roboto", sans-serif;
letter-spacing: normal;
}
#media (min-width: 1000px)
{
.project-cards {
max-width: 40rem;
}
}
ProjectCards.js (Component for actual cards):
class ProjectCards extends Component {
render() {
return (
<div className="card mx-auto project-cards rounded border shadow">
<img className="card-img-top" alt="Project cards"src={this.props.cardImg}></img>
<div className="card-body">
<h5 className="card-title font-weight-bold">{this.props.cardTitle}</h5>
<p className="card-text">{this.props.cardText}</p>
See Project
</div>
</div>
)
}
}
ProjectCard.css:
/* project cards */
.project-cards {
overflow: hidden;
display: inline-block;
text-align: center;
background-color: white;
width: 450px;
height: 450px;
}
.project-cards h1 {
font-size: 1.5rem;
}
/* IMPORTANT: images must be a 2:1 width to height ratio. */
.project-cards img {
height: 50%;
width: 100%;
}
.project-cards .btn {
color: white;
background-color: #52B788;
}
.project-cards a:hover {
background-color: #42966f;
}
You could do something like that with Bootstrap Grid System:
<Row>
{CardData.map((item, index) => {
return (
<Col sm={4}><ProjectCard cardImg={item.cardImg} cardURL={item.cardURL} cardTitle={item.cardTitle} cardText={item.cardText} /></Col>
)
})}
</Row>
Use Bootstrap grid system Grid to place objects on a page. for eg, In your case u want to render 3 card on each row, do the following
<div className="container">
<div className="row">
<div className="col-12 col-lg-4"><ProjectCard/></div>
<div className="col-12 col-lg-4"><ProjectCard/></div>
<div className="col-12 col-lg-4"><ProjectCard/></div>
<div className="col-12 col-lg-4"><ProjectCard/></div>
<div className="col-12 col-lg-4"><ProjectCard/></div>
<div className="col-12 col-lg-4"><ProjectCard/></div>
</div>
</div>
Above code will place each ProjectCard on 1 row on mobile device using col-12 and will place 3 ProjectCards on 1 row on desktop using col-lg-4.
The grid system will also handle any number of ProjectCards, as the 4th ProjectCard will go on to the next line.
Another point to remember is, when using grid system dont specify width for ProjectCard, as the Grid system will handle the width for you.
Updated code
<div id="card-div" className="row">
{CardData.map((item, index) => {
return (
<div className="col-12 col-lg-4">
<ProjectCard
cardImg={item.cardImg}
cardURL={item.cardURL}
cardTitle={item.cardTitle}
cardText={item.cardText}
/>
</div>
);
})}
</div>;
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 ---*/
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;
}
}
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%;
}