How to fix unwanted behavior with CSS transition & flex wrap? - html

I am building a React webpage.
I have a number Cards in a flex row, which expand when hovered over with the mouse. The way I am making them expand is by increasing max-width & by adding a transition clause regarding max-width in the CSS.
At certain screen sizes this works well, but at others the Card that is expanding will wrap around to the next row, which makes the mouse not hover it anymore, which in turn makes it contract & move back up to the initial row, restarting this process. It looks like the page went nuts.
What is a good approach to fixing this unwanted behaviour?
Card:
// this makes the cards expand/contract
const onHover = () => {
cardRef.current.style.maxWidth = '370px';
}
const onExitHover = () => {
cardRef.current.style.maxWidth = '250px';
}
CSS:
.parent {
padding: 20px;
margin: 10px;
border-radius: 20px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
flex-wrap: wrap;
}
.card {
max-width: 250px;
min-width: 250px;
transition: max-width 0.5s;
/* plus the following from react */
/* display:'flex', */
/* flexDirection:'row', */
/* width:'100%', */
/* position: 'relative' */
}
EDIT:
Adding more code for Context
HTML of Parent
<div className="App-content">
<p className="Section-header" style={{color:'red'}}> PROJECTS </p>
<div className="parent">
<NewCard title="Project 1" ...
/>
<NewCard title="Project 2" ...
/>
...
</div>
</div>
Css Of Parent
.App-content {
background-color: white;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.parent {
/* background-color: #ffffff33; */
padding: 20px;
margin: 10px;
border-radius: 20px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
flex-wrap: wrap;
}
React Card Component:
import React, {useState, useRef, useEffect} from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import Typography from '#material-ui/core/Typography';
import { DynamicTag } from './Tag';
import './NewCard.css';
const useStyles = makeStyles({
root: {
margin: 10,
},
title: {
marginBottom: 12,
}
});
export default function NewCard(props) {
const classes = useStyles();
const { title } = props;
const containerRef = useRef();
const onHover = () => {
containerRef.current.style.maxWidth = '370px';
}
const onExitHover = () => {
containerRef.current.style.maxWidth = '250px';
}
return (
<Card onMouseEnter={onHover} onMouseLeave={onExitHover} className={classes.root}>
<div ref={containerRef}
className=".card"
style={{
display:'flex',
flexDirection:'row',
width:'100%',
position: 'relative'}}>
<div style={{minWidth:'250px'}}>
<CardContent>
<Typography className={classes.title}>
{title}
</Typography>
// some content here
</CardContent>
</div>
<div className='Card-image-container'>
<img src={image} className='Card-image'/>
</div>
</div>
</Card>
);
}
Card CSS
.card {
max-width: 250px;
min-width: 250px;
transition: max-width 0.5s;
}

Related

Is there any way in CSS to make other objects move when another object is scaled?

I have a row of elements, and they have a hover animation to make them scale up. Is it possible to make other images next to them change position on scale to prevent the overlap?
body {
background-color:#1a1a1a;
}
img{
max-width: 15%;
transition-duration: 0.5s;
transform-origin: center;
border-radius: 25px;
overflow: hidden;
margin: 50px;
}
img:hover{
cursor: pointer;
transform: scale(110%);
}
<img src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg">
<img src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg">
<img src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg">
and example of the effect I am looking for would be something that looks like this:
This will scale images up and down, dependent on classes. I've amended your css slightly for display purposes and add the JS code (left comments as clear as possible).
// define function to return all siblings of hovered element
function getAllSiblings(element, parent) {
const children = [...parent.children];
return children.filter((child) => child !== element);
}
// grab all img elements
const imgs = document.querySelectorAll('img');
imgs.forEach((i) => {
// define siblings using function above
const siblings = getAllSiblings(i, document.getElementById('parent'));
// *hover in*
i.addEventListener('mouseover', function () {
// add an active class when hovered (amended your css)
this.classList.add('active');
// add small class to all sibling elements
siblings.forEach((sibling) => {
sibling.classList.add('small');
});
});
// *hover out*
i.addEventListener('mouseleave', function () {
// remove active class and small classes so hovered element reverts to normal
this.classList.remove('active');
this.classList.contains('small') && this.classList.remove('small');
// remove class small on all siblings so that everything is reverted to initial display
siblings.forEach((sibling) => {
sibling.classList.remove('small');
});
});
});
body {
background-color: #1a1a1a;
/* added for display purposes */
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
/* added for getting parent element */
#parent {
margin: auto;
display: flex;
justify-content: center;
align-items: center;
gap: 2rem;
width: 100%;
}
img {
max-width: 15%;
transition-duration: 0.5s;
transform-origin: top;
transform-origin: left;
border-radius: 25px;
}
/* added for changing hover states */
img.active {
max-width: 17%;
cursor: pointer;
transform: scale(120%);
transform-origin: center;
}
img.small {
max-width: 17%;
transform: scale(80%);
transform-origin: center;
}
<div id="parent">
<img
src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg"
/>
<img
src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg"
/>
<img
src="https://www.tazzadesign.com/wp-content/uploads/sites/65/2013/11/dummy-image-square.jpg"
/>
</div>
Check this out (after hover, the shape is changing width & height):
const divs = document.querySelectorAll('div');
const reset = () => {
divs.forEach(div => div.classList.remove('active'))
}
divs.forEach(div => div.addEventListener('mouseover', () => {
reset();
div.classList.toggle('active');
}));
divs.forEach(div => div.addEventListener('mouseout', () => {
reset();
}))
section {
height: 150px;
width: 600px;
display: flex;
justify-content: space-between;
align-items: center;
border: 2px solid red;
}
div {
flex: 1;
height: 100px;
border: 2px solid black;
transition: flex .2s, transform .2s;
margin: 1em;
}
div.active {
transform: scaleY(1.5);
flex: 2;
}
<section>
<div></div>
<div></div>
<div></div>
<div></div>
</section>

Image from web doesn't display

I'm building a simple site and trying to src any image from web in Slider (exemple this image) but it doesn't display at all.
import { ArrowLeftOutlined, ArrowRightOutlined } from "#material-ui/icons";
import styled from "styled-components";
const Container = styled.div`
width: 100%;
height: 100vh;
display: flex;
background-color: coral;
position: relative;
`;
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #fff7f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: ${(props) => props.direction === "left" && "10px"};
right: ${(props) => props.direction === "right" && "10px"};
cursor: pointer;
margin: auto;
`;
const Wrapper = styled.div`
height: 100%;
`;
const Slide = styled.div`
display: flex;
align-items: center;
`;
const ImgContainer = styled.div`
flex; 1;
`;
const Image = styled.div``;
const InfoContainer = styled.div`
flex: 1;
`;
const Slider = () => {
return (
<div>
<Container>
<Arrow direction="left">
<ArrowLeftOutlined />
</Arrow>
<Wrapper>
<ImgContainer>
<Image src="https://images.unsplash.com/photo-1611690398208-18158228b6ba?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80" />
</ImgContainer>
<InfoContainer></InfoContainer>
</Wrapper>
<Arrow direction="right">
<ArrowRightOutlined />
</Arrow>
</Container>
</div>
);
};
export default Slider;
It looks like Image is just a styled div:
const Image = styled.div``;
This will be the same as writing (which doesn't work):
<div src="..." />
Instead, try changing Image to be a styled.img:
const Image = styled.img``;
In JSX you should use {} for values of properties. For example <Image src={img.jpg} />
So do this change:
<Image src={https://images.unsplash.com/photo-1611690398208-18158228b6ba?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80} />

Not able to add css in react

**Hii all I am trying to add css in react but not getting any changes in app home page and I also need wants to know how to add this pseudo selector using mui styled **
This is the css file:
lines {
display: 'flex';
flex-direction: row;
}
lines:before, lines:after{
content: "";
flex: 1 1;
border-bottom: 1px solid;
margin: auto;
}
lines:before {
margin-right: 10px
}
lines:after {
margin-left: 10px
}
And this is the home.js file :
import { styled } from '#mui/system';
import styles from './Style.css';
const MyComponent = styled('div')({
backgroundImage : "url('https://images.pexels.com/photos/841130/pexels-photo-841130.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1')",
height:'30vh',**strong text**
backgroundPosition: "center",
marginTop:'-80px',
fontSize:'50px',
backgroundSize: 'cover',
marginRight : '-10px',
marginLeft : '-10px',
backgroundRepeat: 'no-repeat',
textAlign : 'center',
padding: 200,
top: 200,
});
const HomeComp = () => {
return (
<>
<MyComponent> </MyComponent>
<h4 className={styles.lines}> Home Page</h4>
</>
)
}
export default HomeComp;
Try importing your CSS this way
import './Style.css';
and use it by calling the class name directly
<h4 className="lines"> Home Page</h4>
Your imports are correct, but coming to CSS, as they are classes, you have to add a . in front of them
.lines {
display: 'flex';
flex-direction: row;
}
.lines::before,
.lines::after {
content: "";
flex: 1 1;
border-bottom: 1px solid;
margin: auto;
}
.lines::before {
margin-right: 10px
}
.lines::after {
margin-left: 10px
}

Why is Text After Image, Not Inline (React) + Why Won't Hover Line Appear?

Currently trying (and failing) to learn React for a project, and not understanding why the header links appear after the image, if they're in the same wrapper. I made different components for different parts of the navbar, and made a different file for the Logo and NavLinks (each in its own section). Here's the code.
App.js
// Importing NavBar
import NavBar from './components/navbar/NavBar';
// Actual App function, has our code
function App() {
return (
<div className="App">
{/* Navbar Declaration, with statement of what links to add */}
<NavBar />
</div>
);
}
export default App;
NavBar.js
// Importing react
import React from "react";
// Importing styled to be able to style the page
import styled from "styled-components";
// Importing the logo
import Logo from "../logo/Logo";
// Importing the links
import NavLinks from "./NavLinks.js";
// ---------------------------- Stylizing the navbar using styled-components
// Main Wrapper for Navbar
const Wrapper = styled.div`
width: 100%;
height: 10rem;
align-items: center;
padding: 0 1.5 rem;
transition: background-color .5s ease;
z-index: 9999;
border-bottom: 2px solid rgba(255,255,255,.05);
margin-left: 50px;
margin-right: 50px;
`;
// NavBar is separated into left, center and right
// Left side of Navbar
const LeftSide = styled.div`
display: flex;
`;
// Center of Navbar
// Flex is a way to define how much each portion is gonna take of the size given to it
const Center = styled.div`
display: flex;
`;
// Right side of Navbar
const RightSide = styled.div`
display: flex;
`;
// Declaration of navbar links
const navbarLinks = [
"Home Page",
"Illustrator Gallery",
"Art Gallery",
"Challenges"
];
/*const navbarLinks = [
{ title: `Home Page`, path: `/` },
{ title: `Illustrator Gallery`, path: `/illustrator-gallery` },
{ title: `Art Gallery`, path: `/art-gallery` },
{ title: `Challenges`, path: `/challenges` }
];*/
// ---------------------------- Creating the NavBar function/component
function NavBar(props) {
// Setting the return value, or the component
return(
<Wrapper>
{/* For the left side, we want to import the Logo component */}
<LeftSide>
<Logo />
</LeftSide>
<Center>
{/* For the middle, we want to add the different links */}
<NavLinks links={navbarLinks} />
</Center>
<RightSide></RightSide>
</Wrapper>
);
}
export default NavBar;
Logo.js
// Importing react
import React from 'react';
// Importing styled components
import styled from "styled-components";
// Importing the image
import USLogo from "../../assets/images/bunny.png"
// Styling the wrapper for the logo
const LogoWrapper = styled.div`
display: flex;
align-items: center;
`;
// Styling the actual logo, as well as its container
const LogoImg = styled.div`
width: 50px;
height: 50px;
img {
width: 100%;
height: 100%;
}
`;
// Styling the information next to the logo
const LogoText = styled.h2`
text-transform: uppercase;
font-size: 3rem;
font-weight: bold;
margin-left: 4px;
padding-top: 8px;
color: black;
`;
// Creating logo
function Logo(props) {
return(
// First we make the wrapper
<LogoWrapper>
{/* Inside the wrapper we'll have the image, then the text */}
<LogoImg><img src={USLogo} alt="US. logo"/></LogoImg>
<LogoText>US.</LogoText>
</LogoWrapper>
);
}
export default Logo;
NavLinks.js
// Importing react
import React from 'react';
// Importing styling
import styled from 'styled-components';
// Styling the container for the links
const LinksContainer = styled.div`
display: flex;
align-items: center;
`;
// Styling the ul components, or the menu
const LinksMenu = styled.ul`
display: inline-block;
text-transform: uppercase;
letter-spacing: 3px;
`;
// Styling each li
const LinksItem = styled.li`
display: inline-block;
vertical-align: top;
align-items: center;
justify-content: space-between;
margin-top: 15px;
padding: 0 1.1rem;
`;
// Styling each link
const Link = styled.a`
text-decoration: none;
color: black;
font-size: 1.6rem;
margin: 0 2rem;
position: relative;
&:hover{
color: rgb(24, 23, 23);
}
&::after {
content: '';
width: 100%;
height: 2px;
background-color: black;
left: 0;
bottom: -3px;
transform: scaleX(0);
transform-origin: left;
transition transform .5s ease;
}
&:hover::after{
transform: scaleX(1);
}
`;
// Creating the navigation links component
function NavLinks(props) {
return(
// First we do the container
<LinksContainer>
{/* Inside the container, we have the menu of links, then the li, and finally links */}
<LinksMenu>
{/* Each link Menu has a bunch of items, with each item having a link */}
{
props.links.map(
(label) => {
return(
<LinksItem><Link>{label}</Link></LinksItem>
)
}
)
}
</LinksMenu>
</LinksContainer>
);
}
export default NavLinks;
The result shows as follows:
Additionally, if I hover over the text, it doesn't change anything. In fact, it doesn't even add the little blue color indicating it's a link anymore. I'm not sure if this is a syntactical problem, since the same code works fine when using css.
I've checked other answers on here suggesting float: left and the like for the wrapper, but for some reason they don't work. Either I'm putting them in the wrong object, or they should be somewhere else.
Any help is appreciated!

circular border-radius artifacts in css

I am using react and have a circle component that I want to map on the screen. The problem is at certain view sizes I get small artifacts in the circles. Flat ends and only on certain rows of circles.
Circles have flat sides at view width 980px
ball hitbox
container hitbox
.ballholder{
display:flex;
flex-wrap: wrap;
justify-content: space-evenly;
background-color:rgb(206,35,212);
padding:0.5vw;
border-radius: 5%;
border:2px solid black;
}
.aball{
background-image: linear-gradient(to bottom right, white, whitesmoke, rgb(150,150,150));
color:black;
border-radius:50%;
display:flex;
justify-content:center;
align-items:center;
width:2vw;
height:2vw;
padding:0.05vw;
margin:0.20vw;
font-size:1.3vw;
}
Here's the parent component:
import React, { Component } from "react";
import { Switch, Route, Redirect, Link } from "react-router-dom";
import Ball from "./Ball";
import "../App.css";
export default class Ballswitch90 extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
const balls = this.state.balls.map((a, i) =>
a ? (
<Ball p={{ num: i + 1, clicked: false }} />
) : (
<Ball p={{ num: i + 1, clicked: true }} />
)
);
return <div className="ballholder">{balls}</div>;
}
}
Ball component:
import React, { Component } from 'react';
import { Switch, Route, Redirect, Link } from "react-router-dom"
import '../App.css'
export default class Ball extends Component {
constructor(props) {
super(props)
this.state = {
num:props.p.num,
clicked:props.p.clicked
}
}
render() {
return (
<div>
{this.state.clicked
?
<div className="aball">{this.state.num}</div>
:
<div className="aballred">{this.state.num}</div>
}
</div>
)
}
}
I've tried adding a padding and margin but that only changed the size at which the flats show up.
Probably the css rules with height and width make some problems.
You can see this snippet that works well:
https://codesandbox.io/embed/n6jrm1k2l
aball {
border-radius: 50%;
background-color: white;
border: 1px solid darkred;
padding: 1em;
/* Center the text contents */
display: inline-flex;
align-items: center;
justify-content: center;
color: black;
}
.aball:after {
content: "";
display: block;
/* Ensure the element is a square */
height: 0;
width: 100%;
padding-bottom: 100%;
}
.aball__value {
/* Set the height to 0 and overflow to visible to not interfere with the square styles */
overflow: visible;
height: 0;
/* Vertically center text since we set its height to 0 */
margin-top: -1em;
}