So, I have an art website, with each work getting its own page. The works are mostly photos, meaning they have higher resolutions than most screens are capable of displaying - so they need to be resized down to scale, obviously.
To make works easier to look through, I display them such that they take up most of the screen (minus 100px in either dimension), scaling to fill whichever dimension is more limiting:
Work X is square-shaped, and on the average monitor it gets resized so that its height fills the entire vertical space, and its width scales accordingly - preserving the aspect ratio
Work Y is tapestry-shaped, and gets resized so that its width fills the entire horizontal space, and its vertical space gets resized to match that aspect ratio.
I'm currently using a straightforward Javascript script for this, calling a function on the img tag's onload (as well as whenever the window is resized) to calculate the desired width/height of the image and apply that. The problem with using Javascript for this is that there's a delay between when the image begins to load and when it resizes, which makes the page look really ugly for a while, especially when viewing the site on a poor internet connection.
Leading to my question: is there a way to resize images to a certain percentage of screen size, while preserving aspect ratio, in pure CSS?
This answer provides another Javascript solution, but I'd prefer to find a way to do this in pure CSS if possible.
My current script is this:
function setGoodHeight (element) {
if( on mobile ) {
...
}
else {
height_buffer = 100
width_buffer = 100
height_diff_pct = element.naturalHeight / window.innerHeight
width_diff_pct = element.naturalWidth / window.innerWidth
if(height_diff_pct > width_diff_pct) {
var h = element.naturalHeight;
var w = element.naturalWidth;
element.height = window.innerHeight - height_buffer;
element.width = w * element.height / h;
}
else {
var h = element.naturalHeight;
var w = element.naturalWidth;
element.width = window.innerWidth - width_buffer;
element.height = h * element.width / w;
}
if(element.width < 540) {
element.parentNode.setAttribute("style","width:" + 540 + "px");
}
else {
element.parentNode.setAttribute("style","width:" + (element.width + 40) + "px");
}
}
}
Using the vw and vh units in CSS allow you to size things based on the browser viewport rather than parent elements.
If you set the max-width and max-height for the image it should constrain the image to be no bigger than the browser viewport size for any browser size.
#image-id {
max-width: 80vw;
max-height: 80vh;
}
Tell your images to be at most 100% width of the container they are in, and height set to auto will maintain aspect ratio.
.my-image-class {
max-width: 100%;
height: auto;
}
How about using background-size: cover; for this?
Every image can be the background of a div, which in turn has the following properties set.
height
width
background-size: cover;
background: url('img.png') center center no-repeat;
JavaScript is the best answer but if you really want to only use css you can use percentages rather then px these will scale to a given container.
.img {
max-width:100%;
max-height:100%;
}
here is a similar question and answer: StackPost
Related
let's say my body-tag has a background-image with the resolution of 1920 x 1020. When I load my page, my window only has the size of ~800 x 800. I don't want to load the 1920 x 1020 resolution, only the 800 x 800 I'll need to display the backgroundimage.
Any way to achieve this?
http://jsfiddle.net/49qvq7rw/
<div class="give_me_background_plx">
</div>
body,
html {
height:100%;
width:100%;
}
.give_me_background_plx {
background: url("http://placehold.it/1920x1000") center center, 100% 100%;
height:100%;
width:100%;
}
Edit:
See the jsfiddle. When I open that page, I don't want to load the full image to be loaded, rather a smaller version that is exactly the window size. Just like in a img-tag i want to set a height/width for that image, and those should be my window size.
So you want to load a different image regarding the viewport? Use CSS media queries for that:
body {
background: url(image-1920.png);
}
#media(max-width:800px){
body {
background: url(image-800.png);
}
}
Unfortunately, this is something you can only accomplish by Javascript (I personally prefer jQuery).
Because you only want to load one image and not load in another image whenever the window gets bigger (as Roy's answer accomplishes).
The jQuery would be something similar to:
$(document).ready(function() {
if ($(window).width() <= 800) { // if the width is equal to, or smaller than 800 px.
$("body").css("background","url(image-800.jpg) no-repeat"); // load the small image
} else { // if the width is bigger than 800 px
$("body").css("background","url(image-1920.jpg) no-repeat"); // load the bigger image.
}
});
JSFiddle demo with your gravatar
Note: To test the demo, your must load the page with a small width, then reload it with a width bigger than 800px.
The css of the body tag mus be 100% (width: 100%) or else you can use background-size property to set the size of your image in the background.
I am trying to adapt the dimensions of some items on my HTML page to the size of the window. I know it can be done quite easily with JQuery with something like :
$(window).resize(function(){
var width = $(this).width();
$(item).css('height',(height * w / h)+ 'px'); // w and h are variables used to calculate the ratio
});
However I am looking for a way to do it with CSS.
I have an centered item that occupies 40% of the width of the window. So when the width of the window is reduced, the width of the item is reduced too, but the height is the same. So all I want is the ratio to be the same.
You can set the height to 0, and then add a padding-bottom: X% where X is the image's aspect ratio. You can get the ratio with SASS by using
.element{ padding-bottom: percentage(height/width); }
Also, this can be used in conjunction with a background image and using background-size:cover; to make the image responsive.
I have a strange problem, my data gets hidden when I change the height of my browser.
It also disappears in mobile browsers sizes... here is a screenshot:
I am following this tutorial
Here is the page with the issue.
From what I can tell your slide DIVs have height: 100%; as well as your html and body tags. html will inherit it's height from the view-port size. Your content is larger than the view-port as you change the vertical height. Content gets hidden under the elements that come after it. If you remove the background color from all your slides you will begin to see your content overlapping.
What you need to do is remove height: 100%; from your slides. This will cause your slider DIVs to contain/show your content as they will expand to fit the height they actually take up and will prevent element stacking.
What you need is to either have the slide be the view-port size or the content size, which ever is larger. Since you are using jQuery already you could try something like this:
http://jsfiddle.net/z6xrf/
function slideHeights() {
var viewportHeight = $(window).height();
$('.slide').each(function(){
var elem = $(this);
// reset so we can get the correct height of element each time
elem.css('height','auto');
var slideHeight = elem.height(); // height of content in slide
if ( viewportHeight > slideHeight ) {
height = viewportHeight;
} else {
height = slideHeight;
}
elem.css('height', height);
});
}
$(document).ready(function(){
slideHeights(); // for page load
$(window).resize(slideHeights); // for window resize
});
What we did above is create a function that monitors the current size of the view-port and compares it to the height of the slide (total height of slide's content). If the view-port height is larger than content height we use that, otherwise we use the content height for the slide. In the process we reset the min-height value so it is not reading a value we previously set.
We initially fire the function on page load simply by calling it. Then we pass it to the resize function so it gets called when appropriate. See http://api.jquery.com/resize/ for how browser apply the resize event.
It is a problem of height of-course.
Do one thing, set a minimum height of each slide, approx 800 or 900 px. And then test, it will surely work.
.slide {
background-attachment: fixed;
height: 100%;
min-height: 800px; /*set any height here*/
position: relative;
width: 100%;
}
This is a continuation of CSS Display an Image Resized and Cropped. The answer there seems to be okay for that user but I need some help to improve upon that answer...
Q: how can the resize (scale) be related to the size of the image at runtime. i.e. I don't want to hard code something like "width: 320px; height: 221px;" in the style - that works if you know the dimensions of the image up front.
Here are some jsfiddles:
http://jsfiddle.net/VdX68/ - based on the original thread answer. Works if you know the dimension of the image up front.
http://jsfiddle.net/VdX68/4/ - you don't have to know the dimension of the image, but only works for 100% scale. (here I simply removed the width, hight from the .scalePan class.
http://jsfiddle.net/VdX68/2/ - using width and hight as %. This scales the image to the size of the containng div not the image original dimensions.
I'm looking for a way to scale the image to a % of the original dimensions, not a % of the container it is in.
Any help much appreciated.
I understand you want to do this, but I'm not completely sure.
$(document).ready(function() {
var wdth = $('img').width();
var hght = $('img').height();
$('img').css('width', wdth / 100 * 90 + "px"); // new width is 90% width of image
$('img').css('height', hght / 100 * 70 + "px"); // new height 70% height of image
});
Working example: http://jsfiddle.net/VdX68/18/
You don't have to use JQuery, you can do this with regular javascript also.
I want to insert an image in a webpage and I want it to fit in a 120*40 space.
The problem is, original images can have about any size (400*40, 30*220, etc.)
so if I set height attribute to 40, I might find myself with images larger than 120 width. The same goes if I set a 120px width.
If I set both width to 120 and height to 40, well it fits, but the original ratio is lost, and I don't want that.
What would you suggest ?
Get the original properties of the image in javascript and then set one of them (either to 120 width or 40 height) so that the other fits in 120*40 ?
There are a lot images like that in one page so I think this method is a bit heavy...
PHP solution :
<?php
list($width, $height, $type, $attr) = getimagesize($image);
if($width/$height>3)
$height *= 120/$width;
else
$height = 40;
?>
<img src="<?=$image?>" height=<?=$height?>>
see below for a javascript solution and a CSS solution
css properties max-width and max-height are what you need.
My guess is that it will resize itself if it reaches one of these.
I have used this alot in previous web projects.
But i havent used the combination of both yet.
EDIT: I've sais this in a comment, but setting both those properties does work in my tests. It keeps the ratio and resizes by the limit it reaches first. Do not set any width or height properties, these might cause problems
JavaScript is quite fast, so why not try it?
I'd just stick to finding the aspect ratio and adding some checks:
var width = image.width;
var height = image.height;
var ratio = width / height;
if (width > 120) {
width = 120;
height = 120 * ratio;
} else if (height > 80) {
height = 80;
width = 80 * ratio;
}
image.width = width + 'px';
image.height = height + 'px';
As you seem to be using PHP, ImageMagick can resize an image to fit inside of a predefined box. I only know how to do it via CLI, as I don't use PHP, but I bet the PHP code would be simple.
I was actually searching for an answer to a different query but came across yours.
I use this to resize images which I am finding is very handy in a number of my scripts, but what I would suggest is that you resize the image to a little bigger than the longest side of the container and then use css to center the image both horizontally and vertically and set the container with overflow:hidden;
You lose a small bit of the image around the edges but at least they are all inserted without any stretching or squashing.
Hope that helps you or anyone else trying something similar.