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} />
Related
I have a navbar that contains the button that triggers the movement of the main container to the right and brings the nav elements to the right:
The cards in the middle have an animation that modifies their flex-grow when hovering and shows some text:
But when you hit the nav toggle button when one of these sections is being hovered this happens:
What I'm not understanding is that this view is out of the HTML element size and in theory it shouldn't look like this.
This is the code for the card, made with react & styled-components:
import styled from "styled-components"
const CardDiv = styled.div`
display: flex;
flex-direction: column;
position: relative;
justify-content: space-between;
background-color: var(--Scania-Grey-900-transparent);
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
transition: flex-grow .5s;
&:hover {
flex-grow: 2;
}
&:hover .card_description_text {
opacity: 1;
line-height: 1.5em;
}
`
const Title = styled.h1`
font-family: var(--Scania-Font);
text-transform: uppercase;
color: var(--Scania-White);
`
const ImageBackground = styled.div`
background-image: url(${props => props.background_image});
background-repeat: no-repeat;
background-size: cover;
background-position: ${props => props.bg_position};
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
`
const Description = styled.div`
display: flex;
flex-direction: column;
color: var(--Scania-White);
opacity: 0;
transition: opacity .2s, line-height .5s;
line-height: .5px;
`
const Text = styled.p`
font-family: var(--Scania-Font-2);
margin: .8em;
font-size: 1.1em;
`
const Padding = styled.div`
margin: .8em;
`
const Button = styled.a`
padding: .4em .8em;
border: 2px solid var(--Scania-White);
margin: .8em;
text-align: center;
font-family: var(--Scania-Font);
font-size: 1.1em;
`
const Card = ({ background_image, title, bg_position, text, button_text }) => {
return (
<CardDiv>
<ImageBackground background_image={background_image} bg_position={bg_position} role="background_image_card" />
<Padding>
<Title>{title}</Title>
</Padding>
<Description className="card_description_text">
<Text>{text}</Text>
<Button>{button_text}</Button>
</Description>
</CardDiv>
)
}
export default Card
I'm sorry if this question is poor or if I don't know how to ask the question, but I would like to receive some help. Thank you :=)
EDIT:
This is the code of my main component Home():
export default function Home() {
/* This state is for the status of the navbar */
const [statusNavbar, setActiveNavbar] = useState(false)
const changeStatus = () => {
setActiveNavbar(!statusNavbar)
}
return (
<Main>
<Navbar setNavbarStatus={changeStatus} />
<Container statusNavbar={statusNavbar} />
</Main>
)
}
this Container.jsx: is the component that goes after the navbar:
const Container = ({ statusNavbar }) => {
return (
<DivContainer>
<NavbarElements navbarStatus={statusNavbar} />
<Content navbarStatus={statusNavbar} />
</DivContainer>
)
}
export default Container
NavbarElements component is the part which is hidden by default, and when the burger is clicked, it comes to the right. And Content component is where the content is included the cards.
NavbarElements.jsx code:
const Div = styled.div`
position: absolute;
top: 0;
left: 0;
background-color: var(--Scania-Grey-400);
min-height: 100%;
width: ${sizesConfig.left_side_size}%;
padding-right: ${sizesConfig.padding_spacing}%;
transform: ${props => props.navbarStatus ? 'translateX(0%)' : 'translateX(-100%)'};
transition: transform .5s ease;
`
const NavbarElements = ({ navbarStatus }) => {
return (
<Div navbarStatus={navbarStatus} role="Navbar-content">NavbarElements</Div>
)
}
export default NavbarElements
Content.jsx code:
const Div = styled.div`
transform: ${props => props.navbarStatus ? `translateX(${sizesConfig.left_side_size}%)` : 'translateX(0%)'};
transition: transform .5s ease;
flex: 1 0;
display: flex;
`
const Content = ({ navbarStatus }) => {
return (
<Div navbarStatus={navbarStatus}>
<CardsGrid />
</Div>
)
}
export default Content
In case you were wondering, this is the sizesConfig object which is being used to change the sizes easily
Navbar.config.js code:
const left_side_size = 75
const padding_spacing = 100 -left_side_size
export const sizesConfig = {
left_side_size,
padding_spacing,
}
So I managed to find a solution, from this post:
How can I "disable" zoom on a mobile web page?
The answer from #kgutteridge it's incorrect in this case since it has a problem:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
The meta tag above solves my problem about the viewport, but removes the capability of the user to zoom in/out which I read is a bad practice
#SW4 provides a better answer for problems like mine:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
The meta tag above:
Renders the page at the width of the device, don't scale:
Which was exactly what I was looking for.
I'm a visual artist with not that many coding skills. I know some HTML and some CSS but that's it. I like to create a webpage that does the following:
On the left, there is an image with lines. When hovering over a line the window on the right shows an image, movie, or plays a sound. Hovering over the next line triggers another image, movie, or sound.
Anyone can point me in the correct direction? I made a gif to show how it should work...
Simple solution:
Select HTML elements which we want to hover over (left, middle, right), and HTML elements which contain our images/videos/audio etc. (img1, sound, img2)
For every element you want to hover over, you need to add event listener (addEventListener), so you can manipulate your HTML/CSS code with JavaScript.
2.2 Inside each event listener you add or remove class: none, which has CSS value of display: none (this means element won't be shown), depending on what your goal is.
To make images disappear when we don't hover our cursor over the element, we need to again add event listener to elements which already have on mouseover event listener. In this case we use mouseover or blur. When cursor isn't on the element, JavaScript will automatically add none class to it.
const left = document.querySelector('.left-line');
const middle = document.querySelector('.middle-line');
const right = document.querySelector('.right-line');
const img1 = document.querySelector('.image-1');
const sound = document.querySelector('.sound');
const img2 = document.querySelector('.image-2');
left.addEventListener('mouseover', () => {
img1.classList.remove('none');
img2.classList.add('none');
sound.classList.add('none');
});
middle.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.remove('none');
sound.classList.add('none');
});
right.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.remove('none');
});
left.addEventListener('mouseout',() => addNoneClass());
middle.addEventListener('mouseout', () => addNoneClass());
right.addEventListener('mouseout', () => addNoneClass());
function addNoneClass() {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.add('none');
}
* {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
}
main {
display: flex;
width: 100%;
height: 100%;
}
section.left {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.line-container {
width: 150px;
height: 150px;
display: flex;
align-items: center;
border: 2px solid black;
}
.left-line, .middle-line, .right-line {
width: 50px;
height: 90%;
margin: 0 10px;
}
.left-line { background-color: green; }
.middle-line { background-color: red; }
.right-line { background-color: blue; }
section.right {
width: 50%;
display:flex;
align-items: center;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
border: 2px solid black;
}
img {
width: 200px;
height: 200px;
}
.none {
display: none;
}
<main>
<section class="left">
<div class="line-container">
<div class="left-line">
</div>
<div class="middle-line">
</div>
<div class="right-line">
</div>
</div>
</section>
<section class="right">
<div class="box">
<div class="image-1 none">
<img src="https://play-lh.googleusercontent.com/aFWiT2lTa9CYBpyPjfgfNHd0r5puwKRGj2rHpdPTNrz2N9LXgN_MbLjePd1OTc0E8Rl1" alt="image-1">
</div>
<div class="sound none">
<img src="https://sm.pcmag.com/pcmag_uk/review/g/google-pho/google-photos_z68u.jpg" alt="sound">
</div>
<div class="image-2 none">
<img src="https://cdn.vox-cdn.com/thumbor/I2PsqRLIaCB1iYUuSptrrR5M8oQ=/0x0:2040x1360/1200x800/filters:focal(857x517:1183x843)/cdn.vox-cdn.com/uploads/chorus_image/image/68829483/acastro_210104_1777_google_0001.0.jpg" alt="image-2">
</div>
</div>
</section>
</main>
You can do this by the following code example.
HTML:
<div class="lines">
<span id='line-1'>|</span>
<span id='line-2'>|</span>
<span id='line-3'>|</span>
</div>
<div id='output'></div>
JS
const line1 = document.getElementById('line-1')
const line2 = document.getElementById('line-2')
const line3 = document.getElementById('line-3')
const output = document.getElementById('output')
line1.addEventListener('mouseover', () => {
output.innerHTML = 'Content One'
})
line2.addEventListener('mouseover', () => {
output.innerHTML = 'Content Two'
})
line3.addEventListener('mouseover', () => {
output.innerHTML = 'Content Three'
})
I'm trying to space items within a nav bar where I have tags and search bar. I tried space-between, but not show how to properly position the search bar to get it to be slightly larger. Is this some combo of flex-end?
Attempt
Mock-Up
The box on the right should be slightly larger.
Code
Container
const TagsContainer = styled.div`
display: flex;
width: 100%;
margin-top: 15px;
`
export default function Tags() {
return (
<TagsContainer>
<Tag>Algorithms</Tag>
<Tag>Videos</Tag>
<Tag>Books</Tag>
<Tag>Tutorials</Tag>
<Tag>Health</Tag>
<Tag>Finance</Tag>
<Tag>Rants</Tag>
<Tag>Stream</Tag>
<Tag>Music</Tag>
<Search />
</TagsContainer>
)
}
Tag
const TagContainer = styled.div`
height: 100%;
max-height: 40px;
opacity: .8;
text-align: center;
`
const TagStyle = styled.span`
font-family: 'Lora';
min-width: 80px;
color: white;
padding: 10px;
border: 1px solid white;
font-size: 15px;
`
export default function Tag({ children }) {
return (
<>
<TagContainer>
<TagStyle>
{ children }
</TagStyle>
</TagContainer>
</>
)
}
Search
const SearchContainer = styled.div`
color: white;
border: 1px solid black;
flex-grow: 2;
min-height: 40px;
height: 100%;
`
export default function Search() {
return (
<>
<SearchContainer>
This is a search box
</SearchContainer>
</>
)
}
Add flex-grow: 1; to TagContainer to allow all flex items to grow
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;
}
How to make a div appear on click
You can achieve this by using event listeners on mouse click and appending images to the div element like below code snippet:
const addImageDiv = document.getElementsByClassName('add-image')[0];
addImageDiv.addEventListener('click', (event) => {
const elem = document.createElement("img");
addImageDiv.appendChild(elem);
elem.src = 'https://australiahouse.us/sticker-1.png';
elem.setAttribute('style', `left: ${event.clientX}px; top: ${event.clientY}px; width: 25vw;`);
});
.add-image {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
border: 1px solid lightgrey;
}
body img {
pointer-events: none;
position: absolute;
transform: translate(-50%,-50%) scale(.35);
}
<div class="add-image">
<span>some content</span>
</div>
EDIT:
It's a bit trickier to produce a random image of a small set of images, but the best practical way I suggest to create an array of images, then produce a random number and after that get the floor of random number and array length to produce a random index, and at last you can get a random image on each click. (keep in mind in this method, in a small set of images you have to try several times to get a new image on click!)
const addImageDiv = document.getElementsByClassName('add-image')[0];
const imagesArray = ['https://australiahouse.us/sticker-1.png', 'https://australiahouse.us/sticker-2.png', 'https://australiahouse.us/sticker-3.png'];
const imagesArrayLength = imagesArray.length;
addImageDiv.addEventListener('click', (event) => {
const randomNumber = Math.random();
const randomIndex = Math.floor(randomNumber * imagesArrayLength);
const elem = document.createElement("img");
addImageDiv.appendChild(elem);
elem.src = imagesArray[randomIndex];
elem.setAttribute('style', `left: ${event.clientX}px; top: ${event.clientY}px; width: 25vw;`);
});
.add-image {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
border: 1px solid lightgrey;
}
body img {
pointer-events: none;
position: absolute;
transform: translate(-50%,-50%) scale(.35);
}
<div class="add-image">
<span>some content</span>
</div>