I have an inline img that is 1280(w) x 1024(h) and is contained within a div. The divs dimensions are set 100%(w/h) of the viewport with overflow hidden.
I want to use the image as a fullscreen background and require that it fills the viewport completely regardless of dimensions with no borders showing. It must keep its aspect ratio and I would also like the image to be centered at all times. I am aware that to achieve this some of the image will be cropped.
I believe if make the image height match the viewport height and calculate the width based on the images aspect ratio this will work but I am unsure how to do this. Can anyone help?
Many thanks in advance.
Use backstretch http://srobbin.com/jquery-plugins/backstretch/
$("#demo").backstretch("http://urltoimage.jpg");'
set #demo to 100/100% width and height
If you're not 100% glued to using an img tag, you can do the following:
HTML
<div id="background"></div>
CSS
#background {
background: url('path/to/img.jpg');
background-size: cover;
background-position: center center;
width: 100vw;
height: 100vh;
}
Not really an answer to your question but a potential alternative -- have you tried the min-height/min-width CSS properties?
HTML:
<div class="container">
<div class="image-wrapper">
<img src="..." />
</div>
</div>
CSS:
.container {
width: 100vw;
height: 100vh;
background-color: grey;
}
.image-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.image-wrapper img {
position: absolute;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
transform: translateX(-50%) translateY(-50%);
}
Fiddle: https://jsfiddle.net/mkjoyep1/
In the example, .container (your full width/height div), fills the page width vw/wh and the .image-wrapper has its width/height set to 100% which will match the parent's width and height. With overflow: hidden acting as the crop mechanism you can then stretch your image to fill it's container. I've positioned the image in the center with the method explored here.
This appears to work for me on Chrome and Firefox.
*Edited to include html/css
Related
I am currently using the following code to make images fill the entire screen while keeping their aspect ratio.
div {
position: fixed;
top: 0;
width: 100%;
height: 100%;
}
img {
object-fit: contain;
width: 100%;
height: 100%;
border: thin solid black;
}
<div>
<img src="https://placekitten.com/200/300" alt="">
</div>
What this does is resize images which are smaller or larger than the screen to fill the entire screen while keeping their aspect ratio. For example, when using a display in landscape orientation (width > height) an image with portrait ratio (height > width) would be as high as the screen, while there is some space on the left and right. My example should illustrate this.
In these cases, I would like to be able to detect if the user clicks on the image or outside of it. However, with this approach the bounding box of the image fills the entire div and the entire screen, even if it looks different to the user.
What I mean by this is: The div is set to have 100 percent of the width and height of its container. Since its position is set to fixed, it will have the same size as the screen. For the object-fit property to work on the image, I need to assign it a width and height too. When I set those values to 100 percent, the image's so-called bounding box will fill the entire parent/screen, and then the image will take up as much space as it can inside this box while keeping its aspect ratio (see this answer for another explanation). That means it may look like the image only has the same height, and not the same width as its parent, but in reality, it does. You can verify this using the developer tools of your browser, and I added a border to the image to visualise it. This means, however, that I cannot attach an event listener to the image and one to the div to differentiate between clicks on the image and on the blank area, since the image counts as filling the entire area.
What would be the best approach to solve this? Is there a CSS-only-way? The only thing I can come up with is using JS to size the image, which means making it bigger/smaller to fit the screen while making it keep its aspect ratio, and also doing this on every resize. This seems like a lot of work for something so simple.
Try using flex layout. If you change the height and width of div.outer or the dimensions of the image, it will remain centered in one dimension and fill the div.outer in the other. And only a click on the image itself will raise the alert.
div.outer {
height: 200px;
width: 100px;
border: solid 1px black;
display: flex;
flex-direction: column;
justify-content: center;
}
div.inner {
display: flex;
flex-direction: row;
justify-content: center;
}
div.inner,
img {
max-width: 100%;
max-height: 100%;
}
<div class="outer">
<div class="inner">
<img src="https://placekitten.com/200/300" onclick="alert('click')">
</div>
</div>
In general sense, if image covers the whole screen then we cant target the click on the parent div.
But if u go for the little space all on four corners, then we can provide the click on the parent.
Please refer to the snippet below.
Use the Flex on the div to center the img(image) tag.
I have also provided the maximum width and height so that, the img(image) tag will be in boundary of the parent.
I had even provided you on how to force stretch if needed
* { box-sizing:border-box;}
html,body {height:100%;}
body {margin:0;}
div {
position: fixed;
/*stretching the DIV*/
top: 0;
bottom:0;
right:0;
left: 0;
/*added the background-color for identification*/
background-color: #eadefe;
/*new-props*/
display: flex;
justify-content: center;
align-items: center;
}
img {
max-width: 100%; /** changed width to max-width **/
max-height: 100%; /** changed height to max-height **/
border: thin solid black;
}
/**Below is to force strech and keep image proportions**/
div.force-stretch {
padding: 10px; /*provided padding so image and div can both get clicks*/
}
div.force-stretch img {
object-fit:cover; /*added 10px gap so even if stretched there is space for parent div click*/
width: 100%;
height: 100%;
}
<div>
<img src="https://placekitten.com/200/300" alt="">
</div>
You can use the strange behavior of flex to produce the desired result.
document.querySelector('img').onclick = () => {alert('you pet the kitten.')}
body {
margin: 0;
}
.image-holder {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
<div class="image-holder">
<img
src="https://images.unsplash.com/photo-1592194996308-7b43878e84a6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80"
alt="kitten" />
</div>
flex stretches the image's height, if you want to stretch the width use flex-direction: column.
This code solves your problem:
.img-container {
width: 100%;
height: 100vh;
text-align: center;
}
img {
object-fit: contain;
height: 100%;
max-width: 100%;
}
.some-text {
height: 1000px;
}
<div class="some-text"></div>
<div class="img-container">
<img src="https://placekitten.com/500/100" alt="">
</div>
<div class="some-text"></div>
Supposing that you have some elements before and after the image (element .some-text).
You can use the background-size property in CSS to set the size of the background image to fill the entire screen without having a bounding box. You can set the background-size property value to cover to make sure the image covers the entire screen, while maintaining its aspect ratio.
Here's an example:
body {
background-image: url('your-image-url.jpg');
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
This will set the background image to fill the entire screen, without any bounding box or stretching of the image. The background-repeat property is set to no-repeat to prevent the image from repeating and the background-attachment property is set to fixed to keep the image in a fixed position on the screen.
Here I have two images. I have the widths of these two img elements exactly how I want it. The gutter between these two elements and their container is exactly how I want it as well.
After applying vertical-align: top, I noticed that both of these images automatically determine their own height based on the aspect ratio of the source image. As you can see this means the images end up having the same widths (which I defined explicitly) but different heights by a matter of a dozen pixels or so:
I was wondering if there is a way to give both of these images the same height without switching them to be background-image's. Also, if this image feed is 'dynamic' how could I explicitly define the height while not knowing the aspect ratio of the image in question?
So the problem is that if you set the width and height the same on two differently sized images, at least one of them will be distorted.
You could quite easily fix this, as long as the images are relatively similar in size. The idea is, you surround the image with a div and give the div the height and width instead of the image. Then give it the CSS overflow: hidden; and it will crop off the extra bit of the image. You may also need to give it display: inline-block; to get the div's next to each other.
div {
display: inline-block;
height: 200px;
width: 200px;
overflow: hidden;
}
<div>
<img src="http://via.placeholder.com/200x200">
</div>
<div>
<img src="http://via.placeholder.com/200x240">
</div>
Or if you want the image vertically centered:
div {
display: inline-block;
height: 200px;
width: 200px;
overflow: hidden;
position: relative;
}
img {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<div>
<img src="http://via.placeholder.com/200x200">
</div>
<div>
<img src="http://via.placeholder.com/200x240">
</div>
I recommend using aspect ratios. Format your images to be the same aspect ratio at the minimum before uploading. The other option would be converting to BG images if you can't pre-format.
.container {
padding-top: 100%; /* 1:1 Aspect Ratio */
//padding-top: 75%; /* 4:3 Aspect Ratio */
//padding-top: 66.66%; /* 3:2 Aspect Ratio */
}
I think another approach would be setting image height and use actual image content as background image with background-size:contain; this way your image will not be distorted and will always fill the size.
<img src="blank.gif" style="background-image:url(myImage.jpg);background-repeat:no-repeat;background-position:center center; background-size:contain;height:300px;">
If I were you, I would utilize a CSS method of wrapping your images in a container that has overflow set to hidden which will hide the hanging off pixels.
If you feel people will miss out on part of the image, you could use a css animation like I did below when you hover over it. I use translate3d because it utilizes GPU acceleration in browsers.
main {
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
width: 500px;
}
.img-wrap {
overflow:hidden;
height: 15rem;
width: 15rem;
}
.img-wrap>img {
max-width: 500px;
}
.img-wrap:hover>img {
animation: pan 5s;
}
#keyframes pan {
from {transform:translate3d(0,0,0);}
to {transform:translate3d(-100px,0,0);}
}
<main>
<div class="img-wrap">
<img src="http://lorempixel.com/city/500/600">
</div>
<div class="img-wrap">
<img src="http://lorempixel.com/people/800/700">
</div>
</main>
The easiest way to achieve this would be to set the images as the background of your divs. This will not distort the images as setting the height and width on an img element would. You can then define whether to center it or not.
.img {
width: 200px;
height: 100px;
display: inline-block;
margin-right: 10px;
background-size: cover;
background-position: center;
}
<div class="img" style="background-image: url('https://images.pexels.com/photos/23764/pexels-photo.jpg?w=1260&h=750&auto=compress&cs=tinysrgb');"></div>
<div class="img" style="background-image: url('https://images.pexels.com/photos/23388/pexels-photo.jpg?w=1260&h=750&auto=compress&cs=tinysrgb');">
</div>
I have always had this problem, the only solution I found that solves this problem effectively is
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
and have the image displayed via backend like php with inline style
<div class="image" style="background-image: url('pathToImage');"></div>
Say I have an image that has width
width: 100vw;
Is it possible to position a title say 50% of the way down from this image? I can't think of how to do it as the height will be changing based on the vw, so can this be done with CSS only, or do I need Javascript? Either way, how would I do this?
Thanks
Edit: I have tried the various suggestions below but it seems that whenever I try to use solely CSS with position:relative it messes up the rest of my code. Is there a javascript function, therefore, that can calculate the height of the image as a % of the page height, and then can I position my title at say 75% of the height of the image?
I'm not entirely sure if I've understood you correctly or not, but if you want to vertically centre a piece of text over the top of a responsive image, you could do this:
div {
position: relative;
}
img {
width: 100vw;
height: auto;
}
p {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin: 0;
}
<div>
<img src="https://unsplash.it/200/100/?random">
<p>SOME TEXT</p>
</div>
https://jsfiddle.net/fjh6msqL/
Sure, add a parent around the image and set it to inline-block so that it will match the width of the image, add position: relative so that you can absolutely position your title text in relation to the parent, and then either add an element with your title text or use a pseudo element from the parent (that's what I did in this example) and absolutely position that 50% from the top, and use translateY(-50%) to move the image back up 50% of it's own height so it's in the middle of the image vertically. Here is a good article on how to center stuff using CSS https://www.w3.org/Style/Examples/007/center.en.html
div {
display: inline-block;
position: relative;
}
div:after {
content: 'here is your title';
color: white;
background: black;
position: absolute;
top: 50%;
width: 100%;
text-align: center;
}
img {
width: 100vw;
}
<div class="parent">
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</div>
You can't really do that with an image without using some Javascript. The best solution I think would be to use a div element and set it's background-image property to the image you want to display, and then position your title vertically inside the div. Something like this:
<div style="background: url('url-to-image') no-repeat; background-size: cover; background-position: center center;">
<h2 class="title"></h2>
</div>
Vertical positioning can be tricky, but there are ways, for example:
CSS Vertical align middle
With CSS margin:auto , max-height:0 with absolute position actually does the magic. this will center your title text perfectly regardless of screen size. Instead of giving title a width and height we can set top, left, right, bottom property to 0 which actually scale the element to its relative parent's size. Hope this helps.
body{
margin:0;
padding:0;
}
.img-placeholder{
position:relative;
}
.img-placeholder img{
width:100vw;
height:auto;
}
.img-placeholder h2{
position:absolute;
margin:auto;
top:0;
right:0;
bottom:0;
left:0;
max-height:0px;
text-align:center;
}
<div class="img-placeholder">
<img src="http://lorempixel.com/output/sports-q-c-640-480-2.jpg">
<h2>Image Title</h2>
</div>
Hello I have an image in a container that is set to width: 100%.
I was wondering if there's any way to can have a height generated to make it a perfect square.
So say the original image is 450px wide and 300px tall.
The css gives it a width of 100% so it stretches and fills the container, but the image remains rectangular.
Is it possible to do some css or jquery trick to generate a height to make this image a perfect suqare?
I don't care if the image gets cropped or stretched out and looks funky, I just need it to be a perfect square.
Thanks!
So you are free to stretching out the image - this can be a CSS solution:
Make a square container based on the width by using padding-top: 100%
Position the image absolutely by stretching it out to the square container as desired.
See demo below:
.wrapper {
border: 1px solid red;
height: 0;
overflow: hidden;
padding-top: 100%;
box-sizing: border-box;
position: relative;
}
.wrapper img {
width: 100%;
vertical-align: top;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
<div class="wrapper">
<img src="http://placehold.it/400x300" />
</div>
Using straight CSS you can set width and height to 100vw.
You could do so with the following jQuery
var img_width = $('#image').width();
$('#image').css({'height':img_width+'px'});
Hope that helps.
Since you don't care if the image is cropped or distorted, the layout is simple.
Just add overflow: hidden to the container. The image can be any size.
div {
height: 100px;
width: 100px;
border: 2px solid red;
overflow: hidden;
}
<div>
<img src="http://www.placekitten.com/450/300">
</div>
Given a scenario where you don't know the height and width of image elements in advance, let's say that in cases where image height is greater than image width, you'd like to vertically center the image by cropping the same amount of pixels form its top and bottom, such that the new image height matches the image width. For example, if an image has a width of 200px, and its height is 250px, crop 25px from its top and from its bottom.
Here's an example setup:
HTML:
<div class = 'cell'>
...
<div class = 'image_container'>
...
<img ...>
</div>
</div>
CSS:
.cell {
display: inline-block;
float: left;
/* width will be changed by use of '#media screen'.
Smaller browser window -> larger width */
width: 31%;
}
.image_container {
position: relative;
float: left;
width: 100%;
}
.image_container > img {
width: 100%;
}
Is it possible to accomplish the aforementioned center/crop operation using only CSS, or is it necessary to use javascript/jquery for this?
You can use the object-fit CSS attribute. It acts a lot like the background-size attribute.
.image_container > img {
object-fit: contain;
}
Note that this doesn't have full browser support as of now (October 2016) so you may want to look into setting the image as a background on a div and using background-position and background-size to deal with this instead of an <img> tag.
.image_container {
height: 300px;
background-color: cornflowerblue;
image-rendering: pixelated;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALklEQVQoU2NkgID/UBqdYmSESoJobOA/sgKQKTCFMDaKAuqYAHMs3CqiHInXmwDZGBMDEmk6SQAAAABJRU5ErkJggg==');
background-repeat: no-repeat;
background-position: center center;
background-size: 200px;
}
<div class="image_container"></div>
.cover_image {
height: 400px;
background: url('http://lorempixel.com/g/400/200/') no-repeat scroll center center;
background-size: cover;
}
<div class="cover_image"></div>