html/css - displaying content images as background-image - html

I am currently developing a CMS and want to know which way is better for a rendering function of an image (in content):
When I want to crop an image my usual way was following:
Calculate and do the cropping in PHP and cache the cropped image. Then simply render it with an image element.
Now I think there could be a better way:
Simply render a div with e.g. the exact height (width maybe 100% or fixed) and set the image as background-image with background-size: cover; With background-position you can adjust the cropped area.
Because of the rule that you shouldn't display content images as background-image, I have made following measure:
I render the Image inside the div but it's fully transparent and there's an overflow: hidden; on the div. So you can e.g. save the image with right click.
For me the main reasons to use this are following:
It is fully repsonsive: You can always change Sizes and Aspect Ratio and background-size: cover; will always make it look nice (except if you use any bizarre format). So on desktop you can have a 200x200px box and on an other device you could change it to 200x100px without having any problems.
You use the same image for all devices. No caching of different crops (maybe just scale any image above web size down).
This could look like this:
.background-image {
background-image: url(https://placeimg.com/1000/500/nature);
background-size: cover;
background-position: center center;
overflow: hidden;
margin-bottom: 25px;
}
.background-image img {
opacity: 0;
}
.size-a {
width: 200px;
height: 100px;
}
.size-b {
width: 200px;
height: 200px;
}
.size-c {
width: 200px;
height: 800px;
}
.size-d {
width: 800px;
height: 200px;
}
<div class="background-image size-a">
<img src="https://placeimg.com/1000/500/nature">
</div>
<div class="background-image size-b">
<img src="https://placeimg.com/1000/500/nature">
</div>
<div class="background-image size-c">
<img src="https://placeimg.com/1000/500/nature">
</div>
<div class="background-image size-d">
<img src="https://placeimg.com/1000/500/nature">
</div>
HERE as an example
What do you think about this method? What are the benefits and what are the disadvantages? Do you have any other solution?

I vote for PHP way, once you crop it it's easy to place it but what's more important is download speed. With CSS you download whole image and than you just position and/or resize it.

Related

Automatically scale image while keeping aspect ratio

I have an img inside a div tag, and currently I am using the CSS
img {
max-height: 100%;
max-width: 100%;
}
This currently keeps the images fitting inside the div, which is what I wanted. However, if the image file is smaller than the div, the image will not be the maximum size it can be. Is there an easy way to maximise the image, while keeping the image inside the div, and keeping the original aspect ratio?
I've tried setting the height to 100%, with a max-width of 100%, but this distorts the image, which is not what I'm looking for.
I also tried object-fit: contain;, but this doesn't seem to do anything.
Thanks :)
Try doing adding it as background, then you can do this:
div {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#Michelangelo's answer is another way to achieve your objective. If you want your image to be inside a img tag (like your original post), keep your max-width and max-height values, and put one of these inside your CSS class:
1) Keep aspect ratio based on width:
width: 300px; /* Your preferred width */
height: auto;
2) Keep aspect ratio based on height:
width: auto;
height: 300px; /* Your preferred height */
I would also suggest you to take a look at the object-fit property here:
https://www.w3schools.com/css/css3_object-fit.asp
It kinda acts as background-size property when you put values like contain or cover, with the plus that you can specify width and height without complicating your layout / DOM hierarchy. It comes very handy when dealing with intrinsic sizes of elements.
If you want to keep the image as an HTML element and not a CSS background, I would use object-fit. There are browser support limitations with this CSS property.
https://caniuse.com/#search=object-fit
You could use a polyfill to combat this. Such as:
https://github.com/fregante/object-fit-images
An example of what I believe you're after could be:
https://codepen.io/bin-man/pen/NWKNWLm
.image-container img {
object-fit: cover;
}
You can play around with the image sizes and remove object-fit to see how it behaves.
Hope this helps.
I guess this is what you need... Please run the code snippet...
div {
width: 100px;
height: 100px;
}
div > img {
max-width: 100%;
max-height: 100%;
object-fit: scale-down;
}
<div>
<img src="https://www.wellnesspetfood.com/sites/default/files/styles/blog_feature/public/media/images/6615505_950x400.jpg?itok=ylLXPrq6" />
</div>
<div>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/06/Kitten_in_Rizal_Park%2C_Manila.jpg" />
</div>

Having an image within a background always on the same position?

I think I have an impossible task but before giving up on this I want to be sure that it's really not possible. Maybe it's possible with millions of media queries, but that isn't worth the struggle.
However, I have a backgroundimage with a height of 100vh, meaning it's always 100% height of the users window, and a width of 100%. These two things might make my task impossible.
Within the background image I have another image which should always be on that position, no matter what.
I came up with an example. I want the rocket always stay on that rectangle on the planet. I made this possible on my screen, but it could slip on your screen due different screen sizes.
(stackoverflow doesn't allow images with http, so please change the image src to http or take a look at my codepen: https://codepen.io/anon/pen/yjXbPL)
.background {
background-repeat: no-repeat;
background-image: url("https://wallpaper-house.com/data/out/7/wallpaper2you_191762.jpg");
background-size: cover;
background-position: center center;
height: 100vh;
width: 100%;
}
img {
width: 150px;
position: fixed;
top: 240px;
right: 780px;
transform: rotate(-20deg)
}
<div class="background">
<img src="https://www.myiconfinder.com/uploads/iconsets/256-256-7647188dd0df401f7ec5c5358a0af9a1-rocket.png">
</div>
Is this possible?
Use Position fixed as u do.
Use Left and top, not right.
Put the image beside the background div not in it.
Attached codesnippet shows you a solution. It is based on that you put your rocket and background in 2 different divs and stack them by using CSS-index.
Further on, the rocket is positioned fixed and I added a height of the background that makes it a bit scrollable.
Now, to solve the graphical split of the rocket and the background image you would have to create them as 2 different images and place them into each respective div in the HTML (see codesnippet).
In terms of using different devices you would have to test how the rocket might change position and solve that through a combination of media queries, and potentially use % position instead of px (to position the rocket correct):
.background-pic {
position: absolute;
z-index: 1;
width: 200px;
height: 1000px;
background-color: darkblue;
}
.rocket {
position: fixed;
z-index: 2;
width: 50px;
height: 50px;
background-color: orange;
margin: 100px 0px 0px 100px;
}
<div class="background-pic"></div>
<div class="rocket"></div>
The reason why this can be really hard to achieve is because you're using background-size: cover; which means stretch the image while keeping its aspect ratio and crop the image in order to fit its container's height and width. When you combine this with background-position: center center; it will crop on the edges equally. Then finally you're using two different kinds of measurement units: height: 100vh; width: 100%;
The question then becomes, before the image is cropped, what's the new width and height for the image that "cover" is applying?
This is something very difficult for CSS to determine because it requires things like knowing the ratio of your image (2560x1600 has a ratio of 1.6:1), then trying to fit it inside a container of variable width and height such that it is just small enough to fill it, while cropping out anything left out, before it is cropped, what is the actual size of the image?
Both height: 100vh; and width: 100%; will affect its size, in the manner explained above. As this requires comparing the image's original height and width, with the container's width and height to determine how to stretch the image, trying to figure this sort of math out with pure CSS isn't an easy feat for CSS to achieve without some assistance from JavaScript.
A decent solution is to add a bunch of transparency to the rocket image so it has the same size as the background so it can also go through the same "cover" stretching and cropping logic.
Give this a shot:
https://codepen.io/anon/pen/xjrPvM
HTML:
<div class="background" data-comment="2560x1600 has an aspect ratio of 1.6:1">
<div class="rocket">
</div>
</div>
CSS:
.background {
background-repeat: no-repeat;
background-image: url("https://wallpaper-house.com/data/out/7/wallpaper2you_191762.jpg");
background-size: cover;
background-position: center center;
height: 100vh;
width: 100%;
}
.rocket {
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
height: 100vh;
width: 100%;
background-image:
url('your-rocket-on-a-2560x1600-canvas-with-lots-of-transparency.png');
}
Within the codepen I used a base64 encoded version of "your-rocket-on-a-2560x1600-canvas-with-lots-of-transparency.png"
which is just the rocket placed on a 2560x1600 canvas I did in GIMP, transformed it -20.0 degrees moved it around so it's placed where you want it then exported it as a PNG.
Instead of using the image as background, I've used an inline image with the rocket placed on top. Then the rocket and background are made responsive relative to each other.
.background {
position: relative;
}
.background img {
max-width: 100%;
display: block;
}
#rocket {
top: 49%;
left: 47%;
width: 15%;
height: 15%;
background-image: url(http://www.myiconfinder.com/uploads/iconsets/256-256-7647188dd0df401f7ec5c5358a0af9a1-rocket.png);
background-position: top center;
background-repeat: no-repeat;
background-size: contain;
position: absolute;
transform: rotate(-20deg)
}
<div class="background">
<img src="https://wallpaper-house.com/data/out/7/wallpaper2you_191762.jpg">
<div id="rocket"></div>
</div>
Up to some point, it's possible. Here is my solution for that, I have tried and tested your code. These are the changes to fix your code:
Set the position of the image to fixed:
img
{
width: 150px;
position: fixed;
top: 50%;
margin-top: 20px; (adjust some pixels as per your need)
right: 50%;
margin-right: -90px;(adjust some pixel as per your need)
transform: rotate(-20deg)
}
Here is the complete working example:
https://codepen.io/atulraj89/pen/MGooLr

Variable image aspect ratios in a square box

I have a database for house listings with images of the homes for each entry. The images are uploaded by a 3rd party and they send images in random widths and lengths. Some are square-ish, some are portrait, some are landscape, etc. Without using javascript, what would be the best way to have the image completely fill a square div that is a definite size (200px by 200px, for example). I think using the image as a background image of each div and using "display: cover" would work great but not sure of any browser compatibility issues or maybe there is a better way. any suggestions?
If compatibility is what you care about, this is the best way to give everyone a decent experience:
div {
background-position: 50% 50%;
background-size: cover;
width: 200px;
height: 200px;
overflow: hidden;
position: relative;
}
img {
position: absolute;
max-width: 100%;
max-height: 100%;
left: calc(-2000px);
}
<div style="background-image: url(http://placehold.it/400x150)">
<img src="http://placehold.it/500x200" />
</div>
Basically, use background-size to scale where available, and show the image to all browsers that don't support calc. Two birds, one stone.
There are a few ways to do this, but I prefer using object-fit: cover, which is supported by all major browsers except IE. If you need a solution that works for IE and Edge, you can check out how to implement a fallback, or fall back to using background-size: cover.
Avoid explicitly defining the images' size. Instead use this:
max-width: 100%;
max-height: 100%;
JsFiddle Demo
OR if you want to use background-image then center it using:
background-position: center center;
background-size: cover;
JsFiddle Demo

css3 adaptive image in absolute position

I'm stuck on something that should be very simple. I have a page that uses Semantic UI. On that page I have a logo image that is 200px wide by 388px high. The image is positioned absolutely, top left. It does not use any Semantic UI class. I want the image to shrink adaptively to the screen size. I have played about with min and max heights and widths, but the image will not change size at all.
The only way I got it to almost work was to replace the image with a div and set the image as a background. I got that adapting, but I couldn't maintain aspect ratio, and besides, that's not a satisfactory solution.
Here's an example of what I have;
<div class="ui inverted menu">....</div>
<img src="/img.png" class="logo">
<div class="ui page grid">.....</div>
/* css (separate file) */
.logo{
position: absolute;
top: 4px;
left: 6px;
z-index: 2;
min-height: 100px;
max-height: 388px;
width: auto;
}
This is just one of many variants I have tried and I have run out of ideas!
The best solution will be to put the image as a background-image and than set the background-size to cover.
.logo {
background-image: url(path/to/your/image.jpg);
background-size: cover;
}
This way, you'll maintain aspect ratio.
If you don't want parts of your image to be cut off, you can use background-size: contain; instead.
There is an object-fit/object-position method for your problem.
To keep aspect ratio for an img block just use:
object-fit: contain;
For placing img top left:
object-position: 0 0;
Don't forget to stretch image to 100% width and height:
width: 100%;
height: 100%;
Check out fiddle to play with it.
Please notice that this variant is not the best for cross-browser using, since there is no support for object-fit/object-position properties in IE 6-11, Edge and some Mobile Android browsers according to caniuse.
As Simon said before, I'd reccomend you using background-image for cases like this too.

How do you only scale/shrink an image horizontally with CSS?

How do you get the main image to only scale/ shrink horizontally like the pics on this website? Instead of scaling the image it starts to cut out the image's sides when you resize the browser. Heres how it should work: http://castus.co.uk/
The main image on the castus.co.uk website stays at the same height no matter how small you resize the browser but it shrinks the image's sides.. I hope that explains it better :)
I can only seem to get the whole image to scale when I resize the browser.
I am currently using the following code for my img class:
img.mail {
width: 100%;
height: auto;
}
Or do you mean this?
background-position: center;
background-image: url('....');
background-repeat: none;
width: 100%;
height: 100px;
It cut instead of scale like what you have posted.
NOTE: You need to have wide picture to make it work prettily
I use:
max-width: 100%;
height: auto;
They are using a centred background image and allowing the containing element to shrink thus hiding the sides of the image.
e.g.
#feature {
background: url("path/to/img") center 0px no-repeat;
width: 100%;
height: 50px; // Height of image
}
example: http://jsfiddle.net/xY9qT/1/