CSS Resizing Images, keeping formation - javascript

I have a formation of images, as seen here:
The following is the HTML. "second-panel" is the main wrapper, which has the background image of the building. Each "diamond"-shaped image is positioned absolutely, using CSS, with pixel values.
<!-- Second panel -->
<div id="second-panel" class="parallax-wrapper">
<div id="second-panel-diamonds">
<img class="second-panel-diamond" src="images/furniture-min.png" alt="Furniture" />
<img class="second-panel-diamond" src="images/automobile-min.png" alt="Automobile" />
<img class="second-panel-diamond" src="images/jewelry-min.png" alt="Jewelry" />
<img class="second-panel-diamond" src="images/antique-min.png" alt="Antique" />
</div>
<div class="parallax-panel">
...(not relevant)...
</div>
</div>
CSS:
#second-panel-diamonds{
position: absolute;
left: 1%;
top: -5px;
}
#second-panel .second-panel-diamond{
position: absolute;
/* width: 22%; */
width: auto;
height: auto;
max-width: 350px;
}
.second-panel-diamond:first-child{
top: 250px;
left: 90px;
}
.second-panel-diamond:nth-child(2){
top: 80px;
left: 260px;
}
.second-panel-diamond:last-child{
left: 337px;
top: 337px;
}
The problem is when it comes to smaller screen sizes, as the images will obviously start to overflow, since they are given a fixed width and height. I tried setting them to a percentage width and height auto, but then of course they break formation as they get smaller. I tried setting their positions using percentage values as well, but it does not scale properly, according to the resizing of the images AND the resizing of the window.
Is there any way to maintain this formation while scaling the images down, or will I have to just redesign it for smaller screens?

Yes, using CSS #media queries. You just need to decrease the size of the images display (you'd have to not use auto, if needed, calc(auto - px)) for specific screen sizes (don't forget to change each image position later):
#media screen and (max-width: 600px) {
#second-panel .second-panel-diamond {
position: absolute;
width: 50px;
height: auto;
}
}
#media screen and (min-width: 601px) {
#second-panel .second-panel-diamond {
position: absolute;
width: 100px;
height: auto;
}
}

The easiest way to solve the problem would be to merge all images into one PNG graphic and then to set its width and height as percentage values. Do you need the images to be separate?

Related

CSS Image gallery with fixed height and variable width

I would like to create a gallery wall like this image.
Most tutorials I can find on the matter either use grid (which either requires me predefining grid-areas for each image, or have a fixed width and height for each image) or flexbox (which I am trying to get working now).
The critical parts is that the images are displayed left-to-right from the source, and I want the gallery to be generated dynamically due to the images I provide it, so images of different aspect ratios, I want to lock the height of each row to say 200px and have the images keep their aspect ratios but resize to the appropriate height. This is easy if the images were to be vertically stacked, as I could use columns or width: 200px, height: auto, but the other way around doesn't seem to work (width: auto, height: 200px).
Anyway here is my current html:
{images.map((image, index) => {
<div class="gallery">
<div class="pic>
<div class="gatsbyPic">
<picture>
<img src={image.src} />
<picture>
</div>
</div>
</div>
}
I am using Gatsby hence the strange layout, here is how it looks like in Gatsby
<div className={style.gallery}>
{imageData.map((item, index) => {
return (
<div key={`${item.name}_{index}`} className={style.pic} onClick={() => onImgSelected(index)}>
<Img className={style.gatsbyPic} fluid={item.original} />
</div>
)
})}
</div>
</div>
And CSS
.gallery {
display: flex;
width: 1000px;
flex-wrap: wrap;
}
.gallery .pic {
flex: 1;
width: auto;
height: 200px;
min-width: 300px;
object-fit: cover;
}
.gatsbyPic {
height: 100%;
width: 100%;
}
/* AUTOMATICALLY generated by Gatsby */
.gatsbyPic img {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
object-fit: contain;
object-position: center center;
}
This is the result
As you can see, the portrait of the woman is scaled appropriately but it's grandparent container, .pic, is still covering the entire width because min-width: 300px is set. But without the min width, all my pics resize to be very narrow to fit in one line for the flex container, and then you can barely make out any of the images!
How can I get the desired result?

Prevent Content Jumping Below Image as it Loads

I currently have an image that I am giving 100% width. The issue I am noticing is that while the image loads, the content below jumps up to where the image sits while it loads. I know I need to give the image some sort of fixed height, but I want the image to remain responsive. The desired effect: The image looks exactly as it does when applying 100% width and prevents the content below from jumping while the image loads. Please advise on this. My code is as follows:
<img src={"https://storage.googleapis.com/youfit-assets/239315_66400_YouFit_JUL21_Mil_Website_1680x761_CarInitial.jpg"}
alt="travel"
className="image"/>
Styles:
.image {
position: relative;
width: 100%;
height: auto;
max-height: 100%;
}
In order to duplicate what I am seeing test on an incognito browser with the following link https://codesandbox.io/s/gifted-montalcini-ohts8?file=/src/App.js
Wrap your img tag into div, so it should look like:
<div className="image-wrapper">
<img src={...} alt="travel" className="image"/>
</div>
<div style={{ marginTop: 60 }}>TEXT BELOW</div>
then replace your style for image with this style (if your aspect ratio is 4:3):
.image-wrapper {
position: relative;
padding-bottom: 37.5%;
}
.image {
position: absolute;
width: 100%;
}
or if your aspect ratio is 16:9
.image-wrapper {
position: relative;
padding-bottom: 56.25%;
}
.image {
position: absolute;
width: 100%;
}

How to Change Image on hover

I'm attempting to set up a way for users to be able to hover over a small preview of an image and have a "featured" section show this image in its full size. I've managed to accomplish that with the code below.
My problem is when images are very different sizes (one landscape and one portrait It looks very bad and makes the page jump.
Goal: I'm trying to figure out a way to avoid this. I want to find a way to display the main image in a uniformed look. Aka the same size. I want to accomplish this without heavily distorting the images by changing their sizes. Any help is hugely appreciated.
Check out the JS fiddle: https://jsfiddle.net/4hrvxpe2/10/
HTML:
<img id='mainPicture' class="image-resposive" src= "https://images-na.ssl-images-amazon.com/images/I/51EG732BV3L.jpg">
<br>
<br>
<div class='smallerImages'>
<img id='imageNum1' class="small" src="http://i.huffpost.com/gen/4393678/images/o-THE-MATRIX-facebook.jpg">
<img id='imageNum2' class="small" src="https://images-na.ssl-images-amazon.com/images/I/51EG732BV3L.jpg">
</div>
CSS:
.smallerImages{
display:inline-block;
}
#mainPicture{
width: 75%;
height: 75%;
display: table; margin: 0 auto;
}
.small{
max-width: 15%;
max-height: 15%;
min-width: 15%!important;
min-height: 15%!important;
}
Jquery:
$('#imageNum1').hover(function() {
$('.small').removeClass('selectedImage')
var src = $('#imageNum1').attr('src');
$('#imageNum1').addClass('selectedImage')
$('#mainPicture').attr('src', src);
});
$('#imageNum2').hover(function() {
$('.small').removeClass('selectedImage')
var src = $('#imageNum2').attr('src');
$('#imageNum2').addClass('selectedImage')
$('#mainPicture').attr('src', src);
});
Adding a max-height and max-width makes it better.
Check out https://jsfiddle.net/4hrvxpe2/13/
Or you can encapsulate it in a div. Something like
<div class="container"><img src="img.jpg"></div>
and give dimensions to the container, as in:
.container{
height: 100px; width: 200px; overflow: hidden;
}
Check out https://jsfiddle.net/4hrvxpe2/22/
Or
In order for the image to take a fixed size always use a div and set it as its background and make it cover the div:
Check out https://jsfiddle.net/4hrvxpe2/23/
If you don't want the images to affect the rest of the elements in the document you need to take them out of the flow.
This is possible if you give the selected image a fixed position and make use of the transform property.
With that being said, here's a very rough example of how I would do it.
Responsive example (open in full screen and resize the window):
$('#imageNum1').hover(function() {
$('.small').removeClass('selectedImage')
var src = $('#imageNum1').attr('src');
$('#imageNum1').addClass('selectedImage')
$('#mainPicture').attr('src', src);
});
$('#imageNum2').hover(function() {
$('.small').removeClass('selectedImage')
var src = $('#imageNum2').attr('src');
$('#imageNum2').addClass('selectedImage')
$('#mainPicture').attr('src', src);
});
body {
position: relative
}
.smallerImages {
width: 20%;
}
#mainPicture {
max-width: 55vw;
max-height: 75vh;
margin: 0 auto;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.small {
width: 100%;
margin: .5em auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='smallerImages'>
<img id='imageNum1' class="small" src="http://i.huffpost.com/gen/4393678/images/o-THE-MATRIX-facebook.jpg">
<img id='imageNum2' class="small" src="https://images-na.ssl-images-amazon.com/images/I/51EG732BV3L.jpg">
</div>
<img id='mainPicture' class="image-resposive" src="https://images-na.ssl-images-amazon.com/images/I/51EG732BV3L.jpg">
<br>
<br>
My best attempt so far is the following. This works okay but it does distort images that are very tall. Can anyone suggest improvements?
JSFiddle: https://jsfiddle.net/4hrvxpe2/26/
.small{
max-width: 10%;
height: 100px;
min-width: 10%!important;
}
.smallerImages{
margin: 0 auto;
}
#mainPicture{
width: 100%;
height: 600px;
display: table; margin: 0 auto;
}
I accomplished the goal by changing 15% of maximum and minimum width in .small to 15vw.
.small{
max-width: 15vw;
max-height: 15%;
min-width: 15vw!important;
min-height: 15%!important;
}
vw is for the viewport width, while % will take the content size and size it relative to that. When the image changes, because of the image size differences, that image is increasing the content width, meaning that anything using % will change to the new width.
Here's the JSFiddle.

What is the best way to approach this background image issue?

My Goal:
So I am making a webpage with a map of the USA as the "background image" and on top of that map I have about 10 markers pointing to specific location. The markers are NOT part of the picture thats just me adding them with absolute positioning and top and left with a percentage.
The Problem:
As I scale down the page or scroll up and down the markers that I have set with absolute positioning begin to move out of the spot they are suppose to be on because the background-image is getting smaller do to it displaying 100%.
The Question:
How can I achieve what I want with the markers on the map where they are suppose to be not moving as the window is being scaled down?
Now I know of only 1 solution and this solution can take a VERY LONG TIME. What I was thinking is instead of positioning the markers that I want on the map with percentage I can do it with pixels and then use a TON of media queries and keep on adjusting it. Not only is this solution going to take extremely long but it also does not seems like the correct way to go about this.
HTML:
<div class="container main-content"><!--the map background image is set here-->
<div class="row relative">
<div class="eq-content-wrap">
<div class="eq-content">
<div class="marker"></div> <!--the marker that is positioned absolute-->
</div>
</div>
</div>
CSS:
html, body{
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
background: #000;
}
body{ overflow: hidden; }
.main-content{
background: url('assets/img/map1.jpg') no-repeat top center;
background-size: contain;
height: 100% !important;
width: 100% !important;
}
.eq-content-wrap{
position: absolute;
width: 500px !important;
top: 22%;
left: 40%;
}
.marker{
height: 40px;
width: 40px;
border-radius: 100%;
background-color: red;
position: absolute;
top: 50%;
margin-top: -20px;
}
The problem is that your background image's size is set to 100%: background-size: 100%. This means that when the browser tries to scale the content, the background does not scale with it (it stays 100%).
Your best bet is to remove the background-size property completely. This allows the markers to stay in place when the page scales, however, you won't get the full-screen background effect that you currently have (unless you have a larger image).
The background will still move, however, once the browser window width is less than the image's width. This is because you have the background-position set to top center. The center is what causes it to move once the browser window width is less than the image width. Change center to left and it will fix that issue. You'll also need to set the marker's container to be based to the left as well for this to work on wider screens though. Basically, removing all center properties would help, but the screen wouldn't be centered on a wide screen.
Try substituting css :before pseudo element for .marker ; set percentage unit values utilizing calc()
html,
body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
background: #000;
}
body {
overflow: hidden;
}
.main-content {
background: url(http://lorempixel.com/400/300) no-repeat top center;
background-size: contain;
height: 100% !important;
width: 100% !important;
}
.eq-content-wrap {
position: absolute;
width: 500px !important;
top: 22%;
left: 40%;
}
.main-content:before {
content: " ";
height: calc(12.5%);
width: calc(5%);
border-radius: 100%;
background-color: red;
position: absolute;
top: calc(50%);
left: calc(50%);
margin-top: calc(1%);
}
<div class="container main-content">
<!--the map background image is set here-->
<div class="row relative">
<div class="eq-content-wrap">
<div class="eq-content">
<div class="marker"></div>
<!--the marker that is positioned absolute-->
</div>
</div>
</div>
jsfiddle http://jsfiddle.net/o79rpawc/

Fullscreen video without black borders

The problem I have is that the video always gets black bars on the sides or on the top/bottom depending on the screen size.
Any idea how to get it full screen always without showing that annoying black bars? and without using a plugin.
This is my markup:
<div id="full-bg">
<div class="box iframe-box" width="1280" height="800">
<iframe src="http://player.vimeo.com/video/67794477?title=0&byline=0&portrait=0&color=0fb0d4" width="1280" height="720" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</div>
</div>
#full-bg{
width: 100%;
height: 100%;
img{
display: none;
}
.iframe-box{
width: 100%;
height: 100%;
position: absolute;
background: url(../img/fittobox.png);
left: 0 !important;
top: 0 !important;
iframe{
width: 100%;
height: 100%;
}
}
}
Try adding to your CSS
.iframe-box {
max-width: 1280px; /* video width */
max-height: 720px; /* video height */
}
This means that width: 100%; height: 100% will let the element will expand as much as it can, until it hits a maximum height or width of 720px or 1280px, respectively.
If the screen you're viewing it on has a greater resolution, the node will stop expanding and you'll not have black borders.
Further, afaik the following is not valid CSS, are you using a library or something?
#full-bg {
.iframe-box {
foo: bar;
}
}
Edit after answer accepted: I just thought of a completely different way to achieve this, but it would require you to change a lot of your CSS
.fittobox { /* give fit to box an aspect ratio */
display: inline-block; /* let it be styled thusly */
padding: 0; /* get rid of pre-styling */
margin: 0;
width: 100%; /* take up full width available */
padding-top: 56.25%; /* give aspect ratio of 16:9; "720 / 1280 = 0.5625" */
height: 0px; /* don't want it to expand beyond padding */
position: relative; /* allow for absolute positioning of child elements */
}
.fittobox > iframe {
position: absolute; /* expand to fill */
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
If you know the aspect ratio of your video, you shouldn't even need Javascript. You can use a percentage-based padding-top.
I could post code, but I'd recommend you read this entire article anyway.
#Paul S. 's answer works for me for the .fittobox container for 16:9 video aspect ratios but the .fittobox > iframe embed still has black bars with his CSS. Removing the right and bottom positioning fixes it for me (no need for "px" in those 0 values, of course):
.fittobox > iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

Categories

Resources