I'm generating CSS sprites. I want to use these sprites at multiple sizes. I've searched but haven't been able to figure out how to functionally scale a CSS sprite--e.g. if the original sprite is at 150x150 and I want to display it at 50x50, how can I do that? background-size seems to break it.
I can just generate the sprites at the needed sizes, but when I do this via ImageMagick's -resize I take a noticeable resolution hit. Usually, if I find an image is unacceptably low resolution on a webpage, I just make a bigger image and scale its size, functionally increasing the resolution of the image.
Since I can't figure out how to scale a CSS sprite, I'm a bit stuck--how can I achieve arbitrary resolution using a CSS sprite?
The most elegant way you can do this is by using CSS3 background-size, but this is not supported on all browsers (e.g. IE<=8). You might look into IE specific transforms or filters that you can use and then add the -mz-, -webkit-, and -o- selectors to get the effect you want on the browsers you are targeting.
The least elegant way to do this is by faking the sprite scale and positioning.
The HTML
<div class="ex3">
<img src="http://www.placekitten.com/g/600/400"/>
</div>
The CSS
.ex3 {
position: relative;
overflow: hidden;
width: 50px;
height: 50px;
}
.ex3 img {
position: absolute;
top: -25px;
left: -25px;
width: 150px; /* Scaled down from 600px */
height: 100px; /* Scaled down from 400px */
}
The Fiddle
http://jsfiddle.net/brettwp/s2dfT/
I know of no way to change the size of a CSS sprite, sorry.
As for generating the CSS Sprites, try:
http://spriteme.org/
Or for general image editing:
http://www.gimp.org/
You could edit the individual image components, and then use SpriteMe to generate the Sprite. You don't want to generate the sprite and then resize the entire Sprite image, as then your CSS positions for each individual element would be thrown off.
The options I see are:
Either have the sprite's contents in different sizes in one sprite.
Or take the original sprite and manually resize it one time to create a smaller copy of it. Then reference the smaller sprite version for when you need the smaller images.
Related
Firstly, when using CSS with normal image, we set width:50px and this applies OK on both desktop and mobile devices (of course the image quality and natural size is high enough).
However when using CSS sprite with a simple trick with background-position, with that same size (width of 50px), the displayed image will be blurry (due to scaling or something like that).
I know that we must provide a better spritesheet image (with larger size of course). But in that case the width:50px will not work, I mean it must be some larger value as well. I don't know how to determine that value. Because as I said at first, any box/element having width of 50px will be dealt by the mobile devices somehow automatically. If I set a larger value, the result image may have a larger size unexpectedly (although the quality may be as desired).
.item {
background: url(/sprites.png) 0px 0px;
width: 50px;
...
}
How could you deal with this problem?
For anyone caring about a solution that uses PNG sprites, this is exactly what you can do. To help render the sprites smoothly on mobile (as well as high DPI screen) devices we need a larger image (about x2 the sizes, e.g: the normal screen requires a spritesheet width of 500px, you need at least another one with width of 1000px).
All the background-position and background-size are the same on all devices (mobiles & desktop pcs), the only difference here is the background-image. On desktop pcs you can use the normal (small) spritesheet whereas on mobiles you can use the larger one (as mentioned above).
Here are the 2 snippets of CSS code applied for desktop pcs & mobiles:
This is the common CSS:
.item {
background-position: 0px 0px;
background-size: 500px 300px;
background-repeat: no-repeat;
}
This is applied for desktop pcs:
.item {
background-image: url(your_normal_sprites_500.png);
}
This is applied for mobiles:
.item {
background-image: url(your_large_sprites_1000.png);
}
To switch the style/css programmatically for desktop/mobiles, we can take the benefit of window.devicePixelRatio. This is not supported on some old browsers, but it should be available on most popular modern browsers now.
var isHiResScreen = (window.devicePixelRatio || 1) > 1;
if(isHiResScreen){
//pick style for mobile
}
else {
//pick style for desktop pc
}
Of course you should consider using SVG spritesheet instead if possible as #Dejan.S has mentioned in his comments (and of course I've known about this thanks to him). It's very promising :)
We're having a problem when an image (logo) is resized in WebKit, it is jagged for a couple of seconds. We've tried resizing it both by changing width in CSS and using scale transformation. Is there any way to fix this?
http://codepen.io/Znarkus/pen/xbxKLK
Example HTML:
<div>
<img src="http://i.imgur.com/LoN4Mnz.png">
</div>
CSS:
div {
width: 300px;
height: 100px;
background: #ddd;
}
img {
max-width: 100%;
}
div:hover img {
width: 200px;
}
It seems to be a problem with the antialiasing of the images which has a short delay. My searches did not yield any good answers on how to solve this, so I've come up with two possible solutions.
Solution 1
Keep two versions of the image pre-rendered, then switch between the different sizes.
Pros: Perfect rendering
Cons: Takes more memory
Solution 2
User the image-rendering CSS property to disable antialiasing. By adding image-rendering: [browser specific see codepen fork]; to the div, you can see that the rendering of the image isn't as good as without antialiasing.
Pros: All CSS, no extra memory consumption
Cons: Lesser image quality
http://codepen.io/anon/pen/XJWrvJ
EDIT: Solution 3
On second though, there might be a different solution. Images aren't particulary great for rendering text, but since it's a logo I'm guessing you have some kind of special twist on the text or styling. If you can export the logo as svg and render it in a canvas you might be able to get around these problems.
Is it possible to somehow overwrite an image with a new image with background-image?
I wan't to be able to change an image depending if it's retina or not with css.
Example
HTML:
<img id="foo" src="foo.png">
CSS:
#foo { background: url("bar.png") }
Seems a bit of a convoluted strategy to me. Let me suggest a better option for dealing with retina-quality images. The simplest strategy I've seen for this (and I feel the best, at this stage) is to make the image twice the width and height you need it in Photoshop, then save it at a fairly low quality to keep file size down. In your HTML, or in your CSS, or both, set the desired width and height of the image. It will look great on both regular and retina screens that way, and still have a very small file size. And you only need one image, too, which is great.
Try css3 :before :
img{
display:none;
}
img:before{
content: "";
width: 20px;
height: 20px;
background: url("bar.png");
}
I recall it was long ago best practice to hardcode width and height for any image (generally so it allocated appropriate amount of space while loading), but now with most people on high speed and things generally more dynamic, what is the best practice for this? Is it still preferred that any content image have inline size set with html?
It doesn't matter if you set the size using HTML attributes or in a stylesheet, but you should still specify the size for images.
Eventhough images are loaded a lot faster nowadays, there is still a noticable delay between the page being displayed and the images pop up. It's still irritating when the layout of a page changes while the images are loading.
Yes, it is still preferred.
Plenty of people are not on high speed connections, and mobile is becoming more common.
It doesn't have to be inline - you can do it in external CSS. Some older browsers, if you don't specify the size, will just treat it as 0px;
Its always best to use CSS
You could hardcode the image height and width like this
.myimg img {
width: 10px;
height: 10px;
}
your image file itself should be the size you want it to display as, for the most part, if your concerned about slow loading especially! if you've got a 500X800 px image, that you only want to show as 100X200, scale it down! the file size will be much smaller so it will load faster :)
I would say yes if you want to make sure the white space is included in case of the image does not load or during document load. But no if you're scaling/resizing the image with those attributes, as its unnecessary load on the browser and causes image distortion.
If you are designing for cross browser compatibility, then you should at the very least specify the height and width in your CSS for the image itself. I have found inconsistency between FireFox, IE, Opera, etc if sizes are not specified specifically for the image. Due to the fact that each browser, not to mention different versions, handle adherence to HTML Standards differently. I have found that some browsers will do its best to extrapolate the HTML designers intent, while others just croak on the first error. I would also recommend em sizes, rather than pixel or %'s if you intend for the website to be viewed from a mobile device such as a tablet. I will say, however I have just started playing with HTML5 so I don't of the difference in HTML5 with respect to images.
I just answered a similar question on Wordpress Stack Exchange and also on Webmaster Stack. I am posting it here intending to clarify and help more people. (admins/moderators: if this isn't allowed, let me know the proper way to help).
doesn't really means you need to specify width and height in the html. What it means is that is you gotta reserve te proper space and when the image is loaded, the browser doens't have to reflow and repaint the page.
Besides, if you hardcode the dimensions, it kinds of defeats responsive behaviour. If your layout is not responsive, it's ok, but if you want to keep some responsiveness, you could use only CSS to achieve the results.
Most of time, using both width and max-width:100 will do the work, but this post from Smashing Magazine has an interesting technique: instead of using max-width:100%, you can use The Padding-Bottom Hack :
"With the technique, we define the height as a measure relative to the width. Padding and margin have such intrinsic properties, and we can use them to create aspect ratios for elements that do not have any content in them.
Because padding has this capability, we can set padding-bottom to be relative to the width of an element. If we also set height to be 0, we’ll get what we want. [...]
The next step is to place an image inside the container and make sure it fills up the container. To do this, we need to position the image absolutely inside the container, like so:"
.img-container {
padding-bottom: 56.25%; /* 16:9 ratio */
height: 0;
background-color: black;
}
.img-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
I want to display a collection of image thumbnails in a grid. The images will come in a variety of sizes, but I'd like to restrict the thumbnails to a particular size (let's say 200px wide and 150px tall).
What I'd like to find are some magical HTML markup and CSS rules that will
Allow the images to be included in normal <img> elements
Ensure that the thumbnails fit into their 200x150 pixel box, retain their proportions, and are centered in whichever dimension they overflow.
Not require JavaScript or specific knowledge of each image's actual dimensions
I'm not sure if this is possible. I can make a (bad) approximation of what I want with the following markup:
<div class="thumb">
<img src="360x450.jpeg">
</div>
and CSS:
.thumb {
width: 200px;
height: 150px;
overflow: hidden;
}
.thumb img {
min-width: 200px;
min-height: 150px;
width: 200px;
}
This attempt breaks in a variety of ways:
Images that are in portrait orientation will be sized correctly, but will overflow through the bottom of the container, resulting in vertically-off-center cropping.
Images that are wide and short will be distorted in the horizontal dimension because of the hard-coded width and min-height rules.
But without that hard-coded width, images that are larger than the minimum height and width will not be resized at all.
If it's at all helpful, I've put up an example that will (hopefully) illustrate what I'm trying to do, here:
http://overloaded.org/tmp/imgtest/
http://overloaded.org/tmp/imgtest/imgtest.zip
I know that I can solve this problem by omitting the <img> element altogether and instead pulling the thumbnails in as a centered background image on the containing element, but, if it's possible, I'd like to keep the <img> elements in the page.
Thanks for any help or pointers you can provide!
Edit: I suppose I should note that an ideal solution will work in IE 6+ and modern browsers, but any solution that works in IE 9+ and other modern browsers (recent WebKit, Gecko, etc.) will be gladly accepted.
You can (kind of) achieve this with the CSS3 background-size additions: contain and cover.
Live Demo
contain (top picture) fits the entire image, keeping aspect ratio. Nothing is cropped.
cover (bottom picture) fills the containing element either vertically or horizontally (depending on the image) and crops the rest.
Possible, probably.
Also, probably not the best idea. Your big issue to overcome here is orientation of thumbnails. What if you're dealing with a panorama? Certainly, shrinking it down is going to create a very unsightly "squished" image, as would a very tall image. It's rare that everyone deals in 4X3 or 16X9 100% of the time. So, you'll need a mechanism to pad out the image. Even if the ratio is correct, it's not going to resize as cleanly as you could with a program like Photoshop or Gimp.
The other major issue in this thought process is that you're going to be sending massive amounts of unnecessary data to the server via the larger images. It'll take longer to load, fill up the DOM unnecessarily, and overall just inhibit the UI experience.
There are a number of ways to get around this, none of them pure CSS. I've tackled this several times, each in a unique way based on the client. For one client that wanted things totally custom, it was a custom uploader, resizing via iMagick (part of image magic) and custom CSS/Javascript for the album with major interactivity. In another instance, I use Gallery as the backend--handling the thumbnail creation, uploading, titling, cropping, and organizing-- and then just pulled the reformatted image links out of the DB to display them in a more appealing manner. You could save yourself even more trouble and just use something like the Flickr api to pull images for your use.
Here's a tut on using ImageMagick to do thumbnails.
.thumb img {
max-width: 200px;
max-height: 150px;
min-width: 200px;
min-height: 150px;
}
Well I know for thumbs you would want it max and min if you want a smaller image to make it bigger and bigger image to make it smaller.
try to set max-width and height and not min because if the image is not exactly that size it will overflow :)