I want to create an image slideshow, which only shows one image at a time. However, I want to use relative values for every child of the parent container, so that I can easily resize the slideshow. Every image should have the same height and width.
As I already mentioned, I only want to show one image at a time. As a result, the others images need to be hidden with overflow: hidden;. The problem is that my images do not even overflow in Firefox.
.image-slider {
height: 20rem;
width: 20rem;
}
.image-slider .main {
display: flex;
align-items: center;
}
.main .images {
display: flex;
overflow: auto;
width: 90%;
height: 100%;
}
.main .images img {
object-fit: scale-down;
width: 100%;
height: 100%;
}
<div class="image-slider">
<div class="main">
<div class="images">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Red.svg/512px-Red.svg.png" />
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Solid_blue.svg/768px-Solid_blue.svg.png" />
</div>
</div>
</div>
I want that only the red image is displayed, and that the blue one should vanish because it should overflow. I'm pretty sure that the issue is because of my relative values, however I can't explain why. In Chrome, I achieve my desired result with the above code.
How can I create a slideshow, which is easily resizable, sets all images to the same size (regardless of the source width and height), shows only one image at a time and hides the other ones?
If want use this slideshow and size inheritance parent ( in the code below image1 small and image2 large ,but all images same size in display)
(Use snippet in full screen!)
const image1 = document.querySelector("#image1")
const image2 = document.querySelector("#image2")
const circle1 = document.querySelector(".circle.one")
const circle2 = document.querySelector(".circle.two")
console.log(image1)
circle1.addEventListener("click", () => {
image1.classList.add("active")
image2.classList.remove("active")
})
circle2.addEventListener("click", () => {
image1.classList.remove("active")
image2.classList.toggle("active")
})
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
}
.image-slider {
position: relative;
height: 20rem;
width: 20rem;
}
.image-slider .main {
width: 100%;
}
.images {
display: none;
}
.images.active {
margin: 0 auto;
display: flex;
overflow: auto;
width: 90%;
height: 100%;
}
.main .images img {
object-fit: scale-down;
width: 100%;
height: 100%;
}
.circles {
position: absolute;
width: 20rem;
display: flex;
justify-content: center;
align-items: center;
}
.circle {
width: 20px;
height: 20px;
border-radius: 50%;
border: 1px solid black;
text-align: center;
color: white;
background-color: black;
margin: 1rem 1rem;
cursor: pointer;
}
.circle:hover {
color: rgb(0, 0, 0);
background-color: rgb(255, 255, 255);
}
<div class="image-slider">
<div class="main">
<div id="image1" class="images active">
<img src="https://free-images.com/sm/d839/earth_clouds_jpeg.jpg" />
</div>
<div id="image2" class="images">
<img
src="https://free-images.com/lg/52d5/earth_planet_space_planet.jpg"
/>
</div>
</div>
<div class="circles">
<div class="circle one">1</div>
<div class="circle two">2</div>
</div>
</div>
I used width: 300%; for .main then width: 100% for .images, so that three images placed together by display:flex. Also I set overflow: hidden for .image-slider, In order to it shows only one image in a time.
Also, I used setTimeout function, in order to be slide images.
const animate1 = document.querySelector("img:nth-child(2)");
setTimeout(function() {
animate1.classList.add("animate1");
}, 1000);
const animate2 = document.querySelector("img:nth-child(3)");
setTimeout(function() {
animate2.classList.add("animate2");
}, 2000);
.image-slider {
height: 20rem;
width: 20rem;
overflow: hidden;
}
.image-slider .main {
display: flex;
align-items: center;
width: 300%;
height: 100%;
}
.main .images {
display: flex;
width: 100%;
height: 100%;
}
.main .images img {
width: 100%;
height: 100%;
}
img:nth-child(2){
transition: 1s transform;
}
.animate1 {
transform: translateX(-20rem);
}
img:nth-child(3){
transition: 1s transform;
}
.animate2{
transform: translateX(-40rem);
}
<div class="image-slider">
<div class="main">
<div class="images">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Red.svg/512px-Red.svg.png" />
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Solid_blue.svg/768px-Solid_blue.svg.png" />
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Red.svg/512px-Red.svg.png" />
</div>
</div>
</div>
Adding flex-shrink: 0; to the image elements solves the problem.
Related
Hello everyone, I'm trying to setup the main content of the homepage as shown in the image but can't really figure a few things.
Somehow everything I try results in the image to overflow the container and be as big as the page. I don't want to set a fixed size for the image, but rather have it proportional to the view height and width
This is my code right now:
<section class="main">
<div class="main-left">
<div class="container">
<img src="assets/images/wine.png">
</div>
</div>
<div class="main-right">
<div class="container">
<img src="assets/images/oil.png">
</div>
</div>
</section>
.main {
display: flex;
background-color: #f1eee9;
height: 100%;
}
.main-left, .main-right {
display: flex;
flex-direction: row;
}
.main-left {
background-color: #111;
width: 50%;
}
.main-right {
background-color: #1f1f1f;
width: 50%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
width: 80vw;
height: 80vw;
}
.container img {
display: block;
width: 100%;
height: 100%;
}
I haven't yet added the text so it would be REALLY helpful if you could suggest how to do that as well..
You should use : object-fit: cover;
which is documented here : https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
With your exemple I made that (changed container height to 80vh and not vw)
.main-left, .main-right {
display: flex;
flex-direction: row;
}
.main-left {
background-color: #111;
width: 50%;
}
.main-right {
background-color: #1f1f1f;
width: 50%;
}
.container {
width: 80vw;
height: 80vh;
background-color: blue;
}
.container img {
display: block;
width: 100%;
height: 100%
object-fit: cover;
}
You can optimize your code like below it got correct:
<section class="main">
<div class="main-left">
<img src="assets/images/wine.png">
</div>
<div class="main-right">
<img src="assets/images/oil.png">
</div>
</section>
.main {
display: flex;
flex-direction: row;
}
.main-left , .main-right{
flex: 1;
}
.main-left {
background-color: #111;
}
.main-right {
background-color: #1f1f1f;
}
.main > div img {
display: block;
width: 100%;
height: 100%
object-fit: cover;
}
I have the following code:
JavaScript:
import React, { useState } from "react";
import logo from "../Static/white_lotus.jpeg";
import "./LogoSearchProfile_Header.css";
function Header() {
return (
<div className="header">
<div className="header-left">
<div className="header-logo-link">
<img
className="header-logo"
src={logo}
alt=""
/>
</div>
</div>
</div>
);
}
export default Header;
LogoSearchProfile_Header.css:
.header {
display: flex;
align-items: center;
height: 60px;
position: sticky;
top: 0;
z-index: 100;
background-color: white;
border-bottom: 1px solid lightgray;
}
.header-left{
margin-left: 2%;
justify-content: space-between;
display: flex;
width: 50px;
height: inherit;
align-items: center;
background-color: red ;
}
.header-logo > img {
height: 20px;
}
where I'm using this image (white_lotus.jpeg) as my logo:
Currently, this produces:
where the <img> overflows the <div>, and despite everything I try, I can't change the size of the image. Altering the tag header-logo does nothing, it seems. Is there anything I can do? Why does this happen?
Your image itself has the class header-logo and your CSS is selecting its children with >. Try changing your CSS from .header-logo > img to .header-logo or just img.
.header {
display: flex;
align-items: center;
height: 60px;
position: sticky;
top: 0;
z-index: 100;
background-color: white;
border-bottom: 1px solid lightgray;
}
.header-left{
margin-left: 2%;
justify-content: space-between;
display: flex;
width: 50px;
height: inherit;
align-items: center;
background-color: red ;
}
.header-logo {
height: 20px;
}
<div class ="header">
<div class ="header-left">
<div class ="header-logo-link">
<img class ="header-logo"
src=https://i.stack.imgur.com/CSimC.jpg
alt=""/>
</div>
</div>
</div>
Using .header-logo > img is instructing the browser to look at the child of header-logo which in fact there is none.
Your height: 20px is essentially calling to both the image and the class associated with it, which is unnecessary. I would suggest using one or the other, like below.
EDIT ~ you can also use a negative z-index or overflow-y: hidden; to have the overflow of the image appear behind the div. So it doesn't appear to be "larger" anymore.
.header {
display: flex;
align-items: center;
height: 60px;
position: sticky;
top: 0;
z-index: 100;
background-color: white;
border-bottom: 1px solid lightgray;
}
.header-left {
margin-left: 2%;
justify-content: space-between;
display: flex;
width: 50px;
height: inherit;
align-items: center;
background-color: red;
}
.header-logo {
height: 20px;
}
/* img {
height: 20px;
} */
<div className="header">
<div className="header-left">
<div className="header-logo-link">
<img class="header-logo" src="https://i.ibb.co/3WWwMHR/CSimC.jpg" alt="" />
</div>
</div>
</div>
Overflow happens when content exceeds parent height. Make content height match parent/container height, or do not set height with arbitrary fixed measurements.
I think what you are trying to do is the following:
.header-left > img {
height: 20px;
}
Or
.header-logo {
height: 20px;
}
As the img's class is header-logo and the selecter > means an img whose parent has class header-logo which is not the case here.
I have structure like this:
img {
width: auto;
height: 200px;
}
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
}
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
}
.info {
padding: 1em;
border-top: none;
}
<div class='cards'>
<div class="card">
<img src="https://picsum.photos/id/1004/5616/3744" alt="1004" />
<div class="info">
<h3>Greg Rakozy</h3>
<div><small>https://unsplash.com/photos/SSxIGsySh8o</small></div>
</div>
</div>
</div>
on computers with long width image is rendered a little wrong.
how can I fix this so that it displays correctly, i.e. sticks to the '.card' block?
First you need to limit the width of you main container:
.cards {
display: flex;
justify-content: center;
margin-top: 2em;
width: 80%;
flex-wrap: wrap;
max-width: 1440px; /* whatever you desire */
margin-left: auto; /* center the container */
margin-right: auto; /* center the container */
}
Then each image should take 100% for it's container:
.card {
margin: 1em;
box-shadow: 0 0 6px #000;
object-fit: cover;
flex: 0 0 25%; /* each card will be 25% width */
}
img {
width: 100%;
height: 200px;
object-fit: cover;
}
Adding those to .card class
width: 100%;
height: auto;
Google how to make image responsive with css, it's not related to React.
.card {
width: 100%;
height: auto;
}
You can either put those images in a div.img-container and set the div width & height like this.
.img-container {
width: 100%;
height: // as you want;
}
and then put that image inside .img-container and set the image width to 100%.
.container {
width: 350px;
height 350px;
border: 2px solid black;
border-radius: 5px;
}
.container .img-container {
width: 100%;
height: 200px;
}
.container .img-container img {
width: 100%;
height: 100%;
}
.container .card-info {
width: 100%;
height: auto;
}
<div class="container">
<div class="img-container">
<img src="https://picsum.photos/200">
</div>
<div class="card-info">
<h5>Title</h5>
<small>Your link here</small>
</div>
</div>
and either set image width 100% and height auto.
I have the below code and the css. The left image comes properly. However, when adding two images to the right side, it is showing one below the other and size bigger. So I have added styles rightImg with object-fit: scale-down; which reduced the size to some extent, but it is not coming side by side like columns. And still there is more space around the images, it is not aligned to left, top.
<div className="col-md-12">
<div className={styles.Content}>
<img src={imgUriL1} />
<div className={styles.rightside}>
<p>
first text1
<br />
second text2
<br />
Third text3
<br />
</p>
<div classname={styles.rightImg1}>
<img src={imgUriR1} />
</div>
<div classname={styles.rightImg2}>
<img src={imgUriR2} />
</div>
</div>
</div>
</div>;
CSS
.Content {
display: flex;
flex-direction: row;
padding: 15px;
background: #ffffff;
img {
min-height: 270px;
max-height: 320px;
width: 320px;
margin-right: 30px;
object-fit: cover;
}
.rightside {
display: flex;
width: 100%;
flex-direction: column;
padding-top: 8px;
p:first-child {
margin: 0;
font-size: 16px;
}
p {
margin: 8px 0;
font-size: 13px;
}
}
}
.rightImg1 {
position: relative;
width: 100%;
object-fit: cover;
&::before {
content: "";
display: block;
padding-top: 40%;
}
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: scale-down;
}
}
.rightImg2 {
position: relative;
width: 100%;
object-fit: cover;
&::before {
content: "";
display: block;
padding-top: 40%;
}
img {
position: absolute;
top: 0;
left: 150;
width: 100%;
height: 100%;
object-fit: scale-down;
}
}
#media (max-width: 530px) {
.Content {
flex-direction: column;
margin: 15px;
img {
min-height: 0;
width: 100%;
}
.rightside {
padding-bottom: 0;
}
}
}
The display should be like below. The right side images are bigger in size and they should reduce the size to fit into the cells below. Any help highly appreciated.
I have created a snippet using flex width instead of the set widths you had so you can get an idea of the structure. I also added some basic borders, again so you can see the structure. I replaced the images with text and destructured the CSS to default CSS for demonstrative purposes.
If you want to make the right images side by side, make sure to wrap it in a parent container and add display flex to the parent (which automatically puts the children in a row). Using flex to determine widths makes the content flexible and evenly spaced. For example, setting the left content to flex: 1 and the right content to flex: 2 makes it so the right content takes up 2x the space of the left content
.Content {
display: flex;
background: #ffffff;
border: 1px solid black;
}
.leftImg {
display: flex;
flex: 1;
border-right: 1px solid black;
}
.leftImg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.rightside {
display: flex;
flex: 2;
width: 100%;
flex-direction: column;
padding-top: 8px;
}
.rightside p:first-child {
margin: 0;
font-size: 16px;
}
.rightside p {
margin: 8px 0;
font-size: 13px;
border-bottom: 1px solid black;
flex: 1;
}
.allRightImgs {
display: flex;
flex: 1;
}
.rightImg1 {
position: relative;
flex: 1;
border-right: 1px solid black;
object-fit: cover;
}
.rightImg1 img {
width: 100%;
height: 100%;
object-fit: cover;
}
.rightImg2 {
position: relative;
display: flex;
flex: 1;
align-items: flex-end;
object-fit: cover;
}
.rightImg2 img {
width: 100%;
height: 50%;
object-fit: cover;
}
#media (max-width: 530px) {
.Content {
flex-direction: column;
margin: 15px;
}
.leftImg {
border-right: none;
border-bottom: 1px solid black;
}
.rightside {
padding-bottom: 0;
}
}
<div class='col-md-12'>
<div class="Content">
<div class="leftImg"><img src="https://images.unsplash.com/photo-1537151608828-ea2b11777ee8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1878&q=80" /></div>
<div class="rightside">
<p>first text1<br/>
second text2<br/>
Third text3<br/>
</p>
<div class="allRightImgs">
<div class="rightImg1"><img src="https://images.unsplash.com/photo-1523480717984-24cba35ae1ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80" /></div>
<div class="rightImg2"><img src="https://images.unsplash.com/photo-1587300003388-59208cc962cb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80" /></div>
</div>
</div>
</div>
</div>
I have an horizontal scrollbar class="filter_list" into a wrapper div class="wrapper". I want this scrollbar to be always 100% of the wrapper div and I want this wrapper div to be responsive.
It's working fine if I only have one item in my filter list but as soon as I put more than the wrapper width size, it's not responsive anymore.
Here are some pictures to illustrate the problem :
Responsive and working fine :
OK
The scrollbar is blocking the width of the wrapper that doesn't shrink to fit the dimension of the window (we can see that the picture of the girl is no longer it's 100% square size):
NOT OK
Here is the code :
body {
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
width: 800px;
display: flex;
justify-content: flex-start;
flex-direction: column;
align-items: center;
}
.magic_wand {
margin: 15px 0px 20px;
max-width: 50px;
}
.ico_magic_wand {
width: 100%;
height: 100%;
object-fit: contain;
}
.picture_preview {
width: 100%;
margin-bottom: 50px;
height: 100px;
}
.picture_preview img {
width: 100%;
height: 100%;
object-fit: contain;
}
.filter_list {
width: 100%;
background-color: blueviolet;
overflow-x: auto;
white-space: nowrap;
font-size: 0;
}
.filter:last-child {
margin-right: 0px;
}
.filter {
display: inline-block;
height: 150px;
width: 150px;
background-color: blue;
margin-right: 15px;
}
<body>
<div class="wrapper">
<div class="magic_wand">
<img src="img/ico/magic_wand.png" class="ico_magic_wand">
</div>
<div class="picture_preview">
<img src="https://images.unsplash.com/photo-1527514086375-0a7bae9089be">
</div>
<div class="filter_list">
<div class="filter">
</div>
<div class="filter">
</div>
<div class="filter">
</div>
<div class="filter">
</div>
</div>
</div>
</body>
I would like to understand why the div class="filter_list" width won't shrink with it's parent div while reducing the width of the window and how to fix the problem, thanks a lot !
Try this code.. I can't understand your question.. it may ur expectation,, else explain it clearly..
css
.filter {
display: inline-block;
height: 150px;
width: 21.3%;
background-color: blue;
margin-right: 15px;
}
.filter:nth-child(4n+4) {
margin-right: 0px;
}
Please remove ur css code and add this codes.. I think display:flex; is the issue for ur code..
body {
margin:0px;
}
img {
max-width: 100%;
height: auto;
}
.wrapper {
width: 800px;
margin: 0 auto;
text-align: center;
}
.magic_wand {
margin: 15px auto 20px;
max-width: 50px;
}
.picture_preview {
width: 100%;
margin-bottom: 50px;
height: 100px;
}
.picture_preview img {
height: 100%;
}
.filter_list {
width: auto;
background-color: blueviolet;
overflow-x: auto;
white-space: nowrap;
font-size: 0;
}
.filter:last-child {
margin-right: 0px;
}
.filter {
display: inline-block;
height: 150px;
width: 150px;
background-color: blue;
margin-right: 15px;
}
#media only screen and (max-width: 1024px) {
.wrapper {
width: 100%;
}
}