Scale image properly but fit inside div - javascript

I am making an image gallery. This is the HTML for the image:
<div style="width: 84%; height: 100%; float: left; text-align: center;"><img
id="mainimage" style="height: 100%;"
src="http://www.gymheroapp.com/workouts/img/spinner.gif"/></div>
<!-- Loading spinner is temp image, will be replaced by Javascript later -->
It works fine when the image is square, or the width is not too much more than the height. It breaks when the width is too great, though. Example of image overflowing:
Is there a way I could check whether there is overflow within my Javascript? Something like this:
image.setAttribute('height', '100%')
image.removeAttribute('width')
if (image.isOverflowing()) {
image.setAttribute('width', '100%')
image.removeAttribute('height')
}
Even better, is there any way to scale the image properly but fit it withing the containing div?

jquery example
Best fit:
$('img').on('load',function(){
var css;
var ratio=$(this).width() / $(this).height();
var pratio=$(this).parent().width() / $(this).parent().height();
if (ratio<pratio) css={width:'auto', height:'100%'};
else css={width:'100%', height:'auto'};
$(this).css(css);
});
Edit to account for caveat where image is in cache
$('img').on('bestfit',function(){
var css;
var ratio=$(this).width() / $(this).height();
var pratio=$(this).parent().width() / $(this).parent().height();
if (ratio<pratio) css={width:'auto', height:'100%'};
else css={width:'100%', height:'auto'};
$(this).css(css);
}).on('load', function(){
$(this).trigger('bestfit');
}).trigger('bestfit');

Heres a simple CSS solution:
html, body { height: 100%; }
#gallery { height: 100%; width: 100%; position: relative; }
#gallery img {
/* CSS Hack will make it width 100% and height 100% */
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
/* Maintain aspect ratio */
max-height: 100%;
max-width: 100%;
}
<div id="gallery">
<img src="http://cl.vvmonnickendam.nl/files/large/87" alt="Awesome blabla gedoe">
</div>
Fiddle example

Related

Resizing images of different aspect ratios to fit a div without stretching it

I'm making a portfolio website and I am trying to make a simple image browser. I have a container div with size relative to the size of the browser window. I want that div to be able to contain images of different aspect ratios and a caption of fixed height and the width relative to the width of the image. I don't want the div to stretch to contain the images, I want to resize the image (you can see what I mean in the picture below).
illustration of the problem here
I was trying to use javascript to calculate the size of the image, but failed, because I couldn't calculate the element's size before it is actually loaded. This is how I tried to do it (not thinking about the titlebar):
var divAspectRatio = containerDiv.offsetHeight/containerDiv.offsetWidth;
var imageAspectRatio = image.offsetHeight/image.offsetWidth;
if(divAspectRatio>imageAspectRatio){
image.style.height = content_in.offsetHeight;
}else{
image.style.width = content_in.offsetWidth;
}
captionDiv.style.width = image.offsetWidth;
How do I make it work?
If your background image is in a div element, add this to your css, inside the div block:
background-size: cover;
If it's in an img element, add this to your css, inside the img block:
object-fit: cover;
Try using this css element:
object-fit: cover
This way, your image will get resized to fit the containing box!
The desired layout needs some calculation as the placing of an image that has aspect ratio bigger than the aspect ratio of the container differs from one that doesn't. Also to note is that the caption area is required to be only as wide as the displayed image but has a fixed height.
The imgs are wrapped in an 'innerdiv' which will also contain the caption. On loading the image's aspect ratio is found and stored as a CSS variable. Other CSS variables are set up in advance - see the head of this snippet for those that can be chosen. Remaining calculations are done in CSS.
window.onload = function () {
const imgs = document.querySelectorAll('.container .innerdiv .img');
imgs.forEach(img => {
img.parentElement.style.setProperty('--imgratio', img.naturalWidth / img.naturalHeight);
img.parentElement.classList.add(( (img.naturalWidth / img.naturalHeight) > getComputedStyle(img).getPropertyValue("--containerratio") ) ? 'wider' : 'thinner');
});
}
* {
padding: 0;
margin: 0;
}
.container {
/* SET THE NEXT 4 VARIABLES TO WHAT YOU REQUIRE */
--unit: 1vmin; /* the basic unit - must be fixed e.g. vmin, px, ch not % */
--containerw: 40; /* width of a container in these units */
--containerratio: 1.5; /* the ratio of width to height */
--captionh: 4vmin; /* height of a caption including its units (which must be fixed e.g. vmin, px, em */
--containerh: calc(var(--containerw) / var(--containerratio));
display: inline-block;
width: calc(var(--containerw) * var(--unit));
height: calc(var(--containerh) * var(--unit));
position: relative;
border: solid;
}
.innerdiv {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
.innerdiv.thinner {
width: calc(var(--imgratio) * ((var(--containerh) * var(--unit)) - var(--captionh)));
height: 100%;
left: 50%;
transform: translateX(-50%);
}
.innerdiv.wider {
width: 100%;
height: calc((var(--containerw) / var(--imgratio)) * var(--unit) + var(--captionh));
top: 50%;
transform: translateY(-50%);
}
.img {
width: 100%;
height: auto;
}
.caption {
font-size: 2vmin;
background-color: yellow;
text-align: center;
width: 100%;
height: var(--captionh);
position: absolute;
top: calc(100% - var(--captionh));
left: 0;
}
<div class="container">
<div class="innerdiv">
<img class="img" src="https://picsum.photos/id/1016/200/300">
<div class="caption">CAPTION</div>
</div>
</div>
<div class="container">
<div class="innerdiv">
<img class="img" src="https://picsum.photos/id/1016/500/200">
<div class="caption">CAPTION</div>
</div>
</div>
<div class="container">
<div class="innerdiv">
<img class="img" src="https://picsum.photos/id/1016/300/300">
<div class="caption">CAPTION</div>
</div>
</div>

make the browser window as same as the element's size while resizing browser window. or atleast maintain same aspect ratio of browser as element have

while resizing my browser window i can resize the element div in it. But unwanted spaces/scope on left, right, top and bottom are appearing. I want the browser window's size as same as the div have. Or atleast find the aspect ratio of a div and accordingly we maintain same aspect ratio of the browser window. Ex: if div aspect ratio is 16:9, then we make the browser aspect ratio also same so that we can remove the unwanted space/scope in the browser window.
This is a sample script, instead of using div im using canvas. Help me with this.
<style>
*{padding:0; margin:0}
html,body {
width: 100%;
margin: 0;
padding: 0;
}
#main {
margin: 0 auto;
width: 963px;
height: 642px;
}
#preload {
display: block;
position: absolute;
width: 100%;
height: 100%;
margin:auto
}
.loading {
position:absolute;
top: 43%;
left: 47%;
z-index: 2;
display: none;
}
section{
position:absolute;
top:0
}
a1, a2, a3, a4, a5{display:block}
</style>
<div id="main">
<img id="preload" src="preload.jpg"/>
<img class="loading" src="image.jpg" />
<section>
<a1></a1>
<a2></a2>
<a3></a3>
</section>
</div>
<script src="jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function() {
$(window).on('resize', function(){
var maxWidth = $(window).width();
var maxHeight = $(window).height();
var ratio = $("#main").height() / $("#main").width();
if(maxWidth * ratio > maxHeight) {
$("#main").height(maxHeight);
$("#main").width(maxHeight / ratio);
} else {
$("#main").width(maxWidth);
$("#main").height(maxWidth * ratio);
}
$("#preload").width($("#main").width());
$("#preload").height($("#main").height());
$("a1").text(maxWidth);
$("a2").text(maxHeight);
$("a3").text(ratio);
}).trigger('resize');
})(jQuery);
I'm not 100% sure what you are looking for but you can set any element to fill the browser like so...
.element{
width:100%;
height: 100vh;
}

IE10< svg max-width does not set correct proportions

I have prepared a fiddle: https://jsfiddle.net/uj0uhkkq/1/
<div class="papa">
<img src="image.svg" />
</div>
<style>
.papa {
width: 250px;
height: 50px;
}
.papa>img {
max-width: 250px;
max-height: 50px;
}
</style>
In IE 10 and below the image looks like this:
...in any other "recent" Browser the svg has correct proportions.
Is there any way to fix this for IE 10 and below? If not maybe Javascript can calculate the dimensions?
(Why do I not just set the actual height and width of the svg??? Well because I have the img-element load svg-logos of clients dynamically - of course each has different dimensions)
the natural height/width of the svg image is 601x601 (see source for https://upload.wikimedia.org/wikipedia/commons/f/f4/I-8_%28AZ%29.svg), viz a square... so the max-height (or height) and max-width (or width) rules must be the same to maintain the aspect ratio....
<div class="papa">
<img src="image.svg" />
</div>
<style>
.papa {
width: 250px;
height: 50px;
}
.papa>img {
width: 50px;
margin:0 auto;
}
</style>

How to move elements on mouse scroll?

Here is my html and css code snippet:
.clouds {
background-image: url('http://placehold.it/1200x1200');
background-repeat: no-repeat;
display: block;
}
.cloud-1 {
width: 138px;
height: 83px;
position: absolute;
left: 200px;
top: 350px;
}
.cloud-2 {
width: 100px;
height: 52px;
position: absolute;
left: 625px;
top: 400px;
background-position: -935px -9px;
}
.cloud-3 {
width: 110px;
height: 58px;
position: absolute;
left: 450px;
top: 350px;
background-position: -1033px -6px;
}
<div id="animations">
<div class="clouds cloud-1"></div>
<div class="clouds cloud-2"></div>
<div class="clouds cloud-3"></div>
<div class="clouds cloud-4"></div>
<div class="clouds cloud-5"></div>
<div class="clouds cloud-6"></div>
<div class="clouds cloud-7"></div>
<div class="clouds cloud-8"></div>
<div class="clouds cloud-9"></div>
<div class="clouds cloud-10"></div>
<div class="clouds cloud-11"></div>
<div class="clouds cloud-12"></div>
<div class="clouds cloud-13"></div>
</div>
What I want to achieve is to move clouds to the website edges when user scrolls down. My clouds is one image sprite, and each cloud is positioned absolutely. Sorry, but I am new to web development and still need to learn a lot.
This is best achieved by Javascript, I think. By using JQuery, this should not be too hard.
Check how far you are scrolled, first:
var scrollPercent = 100 * $('body').scrollTop() / ($('body).height()
that gives you the percentage you've scrolled down. Then, you could do something like:
$('.cloud-1').css('left', (200 / scrollPercent) + 'px');
That will set the image 200 px from left at the start, towards 2 px to the left if the user is down the page.
Update those values on scroll:
$('body').on('scroll', function(){
// methods described above here
}
note
The code is not tested, its a heads up in the right direction. Adjust to your needs, and check out the jquery docs.
your code snippet is not working to me (because you used relative path to your image...) but you should probably do it like that (replace the height with the height the user has to scroll)
JQuery :
$(window).scroll(function() {
var scr = $(window).scrollTop();
var height = 300px;
if(scr > height) {
$(document.body).addClass('fix-clouds'); /* add the class on scroll */
} else {
$(document.body).removeClass('fix-clouds'); /* remove when we go back to top */
}
});
CSS :
.fix-clouds clouds {
your CSS
}

Div Square, width size based on 100% height

I'm trying to make a responsive square with the width size based on the (100%) height of the element. I believe it's impossible using only CSS.
The square width should be equal to the height (100% of the large container. The large container is more than 100% of the screen). The ratio has to be width=height to keep the square.
You could do this with a tiny inline image.
No JS, no extra files.
.container {
height: 150px;
width: 100%;
text-align: center;
background: #acd;
}
.square {
display: inline-block;
height: 100%;
background: #691;
}
<div class="container">
<div class="square">
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" height="100%">
</div>
</div>
For a CSS-only solution (where you're sizing relative to the screen size), use viewport units. For example:
#media screen and (orientation:landscape) {
.box{
height: 100vh;
width: 100vh;
}
}
#media screen and (orientation:portrait) {
.box{
height: 100vw;
width: 100vw;
}
}
(You may want to reduce it to 98 units to eliminate scrolling)
Works great for divs that need to take up a precise proportion of screen space.
JSFiddle here.
Take a look... at the aspect-ratio property.
This property makes creating a square div based on height, in the easiest method possible. Here's some example code:
h2 {
font-family: calibri;
}
#parent {
height: 96px;
width: 256px;
background: grey;
margin-bottom: 16px;
}
#child {
height: 80px;
aspect-ratio: 1 / 1;
background: lightgrey;
}
#anotherParent {
height: 96px;
width: 256px;
background: grey;
}
#anotherChild {
height: 50%;
aspect-ratio: 1 / 1;
background: lightgrey;
}
<h2>Absolute height (80px/96px)</h2>
<div id="parent">
<div id="child">
</div>
</div>
<h2>Relative height (50%)</h2>
<div id="anotherParent">
<div id="anotherChild">
</div>
</div>
Here are a couple of links to help you understand the aspect-ratio property:
https://css-tricks.com/almanac/properties/a/aspect-ratio/
https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
https://support.squarespace.com/hc/en-us/articles/115008538927
Since a square has same width and the height, and you know the width of the square, you can apply the same value to height.
If you can use JS, then please try this: (jQuery)
var wiDth = $('div').css('width'); // get width
$('div').css('height', wiDth); // apply that value to the height
Try it here: http://jsfiddle.net/afzaal_ahmad_zeeshan/vpGUK/
You can accomplish this using javascript. I'm assuming that you have a larger div container, in which you want a square, whose height is the same height as the container. The html is as follows:
<div id="container">
<div id="square" style="height:100%;">
</div>
</div>
In javascript, you would simply do:
<script>
var container = document.getElementById("container");
var square = document.getElementById("square");
square.style.width = container.style.height;
window.onresize=function(){
square.style.width = container.style.height;
};
<script>
Hope that helps
I think this can be a good 'css only' solution for you.
Cross browser working.
http://absolide.tumblr.com/post/7317210512/full-css-fluid-squares
Good to highlight this nice css rule:
If the vertical paddings (and margins) are specified in percent (%) values the size is a percent of the width of the containing element.
Put it on your <script src="http://code.jquery.com/jquery-1.10.2.js"></script> and try with jquery:
var totalHeight = 0;
$("#yourContainer").children().each(function(){
totalHeight += $(this).height;
});
$("#yourContainer").css('width', totalHeight + 'px');
Ok here the solution.
<div id="square" style="background-color:black;height:100%">test</div>
$(window).ready(updateWidth);
$(window).resize(updateWidth);
function updateWidth()
{
var square = $('#square');
var size = square.height();
square.css('width',size);
}
http://jsfiddle.net/j372H/7/
You can assign width and height to the container like this
.container {
width: 100vh;
height: 100vh;
}
It will create a square div with 100% height and width=height.

Categories

Resources