CSS Sprite is squashing rather than cropping - css

So I am trying to make some images into a sprite. I thought I understood pretty well what I was doing, but then instead of getting 6 different images, I get 1 squashed image 6 times.
Here is my code
img.sprite
{
width:100px;
height:100px;
background-image:url(myimage.jpg) 0 0;
}
img.sprite2
{
width:100px;
height:100px;
background-image:url(myimage.jpg) -100px 0;
}
</style>
</head>
<body>
<img class="sprite" src="myimage.jpg" width="1" height="1" />
<img class="sprite2" src="myimage.jpg" width="1" height="1" />
When I post this, my image is just squashed so I have 6 images of my sprite being resized and distorted, when I want it to give me a resized image of only a portion. It is not cropping for some reason.

Your are combining background images with inline images, this will not work. The background image is for use on things such as divs and other page elements.
also in your css you have the position coordinates within the 'background-image' property, this will not work either, it either needs to be in the generic 'background' css property or the specific 'background-position' one. see http://www.w3schools.com/cssref/css3_pr_background.asp
if you need to use it on inline images try this technique using css clip http://css-tricks.com/css-sprites-with-inline-images/

Related

Scaling an image sprite, using percentage: Possible?

I just received help in another question I recently asked here in regards to sprites, but now that I have them working properly, I have run into another problem: How can I scale the image displayed?
My current code is as follows:
<div class="index1"></div>
And CSS:
img.index1 {
margin:auto;
width:258px;
height:300px;
background:url("../Images/index.png") 0px 0px;
}
This is the basic code that works as is, to display the appropriate image from the sprite at an absolute dimension of 258*300 pixels. Problem is, I also want to set the width to be 40%. Here is what I tried:
.index1 {
margin:auto;
width:40%;
max-width:258px;
height:300px;
background:url("../Images/index.png") 0px 0px;
}
If I were to use normal images (ie, not sprites), I'd simply set the width to 40%, and the image scales nicely to the containing div. This would be in a ratio, so the height decreases as well, without any distortion or image cutoff. Using the CSS above, the image is unscaled, and because the width is lowered, the sides are cut off.
The aim here is to have the width adjust accordingly, to different browser widths, and simply put, I want to replicate the image behaviour exactly the same way as it would be with a simple image with a percentage width set on it. I have thus far failed at it. And no, I cannot work around the scaling issue.
EDIT: I should also mention that adjusting the browser width merely adjusts how much of the image is cut off.
Solution:
First off, this only works if you have multiple images of the same size (perhaps of the same ratio, but I haven't tested). So I'll try and explain the solution as best I can, with the help of a hypothetical example:
Firstly, you need a placeholder image. This image MUST be the same size, or ratio, as the images you will be displaying. Doesn't matter what the image content is, but I went with a transparent image.
Now, let's say you want 5 images in your sprite, and they will be displayed on your homepage. Let's call these images index1.png, index 2.png etc. Here is the HTML to display it:
<div class="stretch15">
<img class="trans" src="Images/trans.png">
<img class="sprite sprite1" src="Images/index.png" />
</div>
<div class="stretch15">
<img class="trans" src="Images/trans.png">
<img class="sprite sprite2" src="Images/index.png" />
</div>
<div class="stretch15">
<img class="trans" src="Images/trans.png">
<img class="sprite sprite3" src="Images/index.png" />
</div>
<div class="stretch15">
<img class="trans" src="Images/trans.png">
<img class="sprite sprite4" src="Images/index.png" />
</div>
<div class="stretch15">
<img class="trans" src="Images/trans.png">
<img class="sprite sprite5" src="Images/index.png" />
</div>
You'll notice that there are two images inside a div. I'll get to the significance of the div class name in a moment. The trans class shows the transparent image, and the "sprite sprite5" classes show the actual image. I have two classes assigned for this image, just to keep the number of lines in my CSS to a minimum, and to make global image changes much simpler. You'll also notice that the difference between the contents of the five divs is simply the second class name for the second image changes from sprite1 to 5. I'll also explain this in a moment.
Now for the CSS:
.stretch15 {
width:15%;
max-width:258px;
overflow:hidden;
position:relative;
margin:0px auto;
display:block;
}
.trans {
width:100%;
height:auto;
display:block;
margin:0;
padding:0;
}
.sprite {
position:absolute;
top:0;
max-width:none;
max-height:100%;
display:block;
}
.sprite1 {
left:0;
}
.sprite2 {
left:-100%;
}
.sprite3 {
left:-200%;
}
.sprite4 {
left:-300%;
}
.sprite5 {
left:-400%
}
I used the class name 'stretch15' to show the width of the div. I use multiple div widths, so, I used some arbitrary name 'stretch', and then a number to let me know what the width is. So stretch15 tells me the div will be 15% wide, as seen in the CSS. By changing the width in the CSS for this div, you essentially replicate the function of (which I am aware isn't valid code, but it's the simplest way to show it).
As for sprite1 to 5, they all share the same styles in the sprite class, so all that was left was for me to identify which 'left' position to start displaying an image from. This is why the images have to all be the same size. If you move -100% to the left (or 100% to the right), you should land on the left side of the second image. -200% left gets you to the third image, and so on.
As for the rest of the stuff, I honestly wasn't too sure why they were there, other than the fact they they work. What I did was view the source code over here. Also, it really helps if you have something like Firebug (Firefox extension), where you can disable styles to see how things are affected. It will help you understand a lot.
If you'd want a simple fix without worrying about crossbrowser-issues, I'd suggest to use a normal image.
Next, one could use data URIs or use a combo of zoom for webkit/ie and -moz-transform:scale for Firefox or finally break your head on background-size calculations.
You might also want to read: How can I scale an image in a CSS sprite
Hope this helps!
not too sure if i totally get what you mean .
If you want to strectch(?) image on it's width,
you need to get the ratio of the part of your sprite you want to be seen
http://codepen.io/gcyrillus/pen/fjCdD here 'background-size is 100% 232%.
Resize windows width untill box reaches max-width:40%.
maybe a better exemple keeping ration of the sprite and container :
http://codepen.io/gcyrillus/pen/KuJDl

CSS sprite displaying all images

I am trying to use 1 single image file containing 4 images and display them using CSS sprite. Somehow, all 4 images are displayed. I was referring to one of the examples in w3schools.
<div id="ViewTypeContainer" style="float: right; margin-top: 10px; margin-right: 10px;">
<img id="calendarView" alt="" src="/Images/ButtonToggle.png" height="1" width="1"/>
<img id="grdView" alt="" src="/Images/ButtonToggle.png" height="1" width="1" />
</div>
CSS:
#ViewTypeContainer img#calendarView {
width:82px;
height:82px;
background: url('/Images/ButtonToggle.png') 0 0;
}
#ViewTypeContainer img#grdView {
width:82px;
height:82px;
background: url('/Images/ButtonToggle.png') -30px 0;
}
My image file is in .png format:
Can anyone spot my mistake? Thanks.
Yeah: your img tags have their src attributes pointing at the sprite image too.
If you want the sprite image to show up with the positioning specified in the CSS, the images need a transparent image in their src attribute.
Working example using your image here (I've used a data-URI for the transparent GIF):
http://jsfiddle.net/7Ns8L/
And here's another example using what might be more semantic HTML (depending on what these controls actually do), i.e. no <img> tags:
http://jsfiddle.net/7Ns8L/1/
Exactly. You're giving a background image to an image. So the IMG tag is displayed as normal size right over the top of your sprite. The concept of sprites is easiest applied if you work with background-position css property. You could either go through the trouble of generating a transparent .png for your IMG tag source (I wouldn't recommend it), or just replace the IMG tag with a div and give the div the same ID and CSS.

Embedded SVG (with fallback) without using jQuery

I need a way to 1) embed an SVG with a PNG fallback, and 2) use CSS in an external stylesheet to style colors on certain parts of the SVG while 3) without using jQuery.
Background:
At work we link to the same resources on our servers across multiple websites, so this way if we have an update to the resource we don't have to individually update it on 20 sites. An external stylesheet is used so we can make the resource (in this case the SVG) mimic the theme of whatever website we place it on.
My Solution:
I originally did it with jQuery but then was told by my boss that we need a plain JS solution since he doesn't want to have to load jQuery on some of the old sites we have (this sounds silly to me, but I'm not the boss).
My original solution used:
http://www.noupe.com/tutorial/svg-clickable-71346.html (solution 3a.) for the SVG fallback, and
How to change color of SVG image using CSS (jQuery SVG image replacement)? for embedding an SVG.
<a href="link-to-another-page" >
<img class="svg" src="awesome.svg" alt="An awesome SVG" width="186" height="235" onerror="this.removeAttribute('onerror'); this.src='not-as-awesome.png'" />
</a>
<!--followed by the jQuery code in item #2-->
It works great, but uses jQuery. I am a JS beginner, so trying to convert the jQuery code over to regular JS has proved too confusing for me.
Any suggestions would be helpful, but like I said, this needs to:
Be clickable
Not use jQuery
Allow for SVG styling in an external stylesheet
I would suggest you remove your <img/> tag completely and use some tag with background image instead
for example you could use some your link instead:
<style>
.logo {
display: inline-block;
width: 400px;
height: 200px;
background-color: #some-color;
background-image: url('url.png');
background-image: url('url.svg'); //browsers that not support svg should ignore it completely and .png background would be applied and modern browsers would reassign background image
}
</style>
<a class="logo" href=""></a>
another method would be to embed svg directly since it's no problem in html5:
<style>
​svg {
background: #f7f7f7;
border: 1px solid #efefef;
}
​.logo {
display:inline-block;
width: 400px;
height: 200px;
background: yellow url('some iamge url here');
}​
</style>
<a class="logo" href="">
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1" baseProfile="full"
width="100%" height="100%" viewBox="0 0 700 400">
<rect x="100" y="100" width="500" height="200" fill="white" stroke="black" stroke-width="20px"/>
</svg>
</a>​
the good thing is that html5 has no issues applying display: block to link elements i think there shouldn't be any with inline-block and since you wanted to wrap your logo with a link tag it should be perfect solution even ie7 has no problems applying display: block with link elements like with any other inline elements. I prefer the first method since it has better browser support you can check it embed inline SVG and SVG as background image
P.S
style tags have no place within your html but i think everyone knows it:)
and if you don't know how to use inline svg just open inkscape it has xml editor and there you can just copy your svg and paste it within html.
SVGeezy is just what you are looking for:
https://github.com/benhowdle89/svgeezy
it's a js file that's just a few lines that deals with bitmap fallbacks in pure javascript.

Scale image with css to both width and height to scale

The bounding box is approx 1000x600, and some images are 500x100,
while some others are 400x100 (extreme examples). Now I'd like to
scale both up to the maximum size the bounding box is capable to
handle, but keep them to scale.
img {
width: 100%;
height: 100%;
}
Won't keep the image to scale.
You can set only width or only height to 100%. E.g.
img {
width: 100%;
}
or
img {
height: 100%;
}
That will preserve the image scale, but the image might overflow the container.
This might not work in all browsers, but it does in the latest versions of Firefox, Chrome and Opera. I've had weird experiences with this in the past and my solution was to calculate the new image size on the server.
I was having difficulty with this until I read this thread (resize view width, preserve image aspect ratio with CSS), and the List Apart article (http://alistapart.com/article/fluid-images) and put it all together.
If your markup is like this...
<img src="myImg.jpg" />
...then simply stating
img {
width:100%
}
should be enough because most modern browsers realise that most people, given a choice, don't want to change the aspect of their images. However, if your markup contains dimension attributes like...
<img src="myImg.jpg" width="400" height="400" />
...which, is meant to be better technique, then the markup will shine through the CSS keeping the image at fixed height but flexible width (urgh!) unless you tell it otherwise with something like...
img {
width:100%;
height:inherit;
}
...or...
img {
width:100%;
height:auto;
}
Both seem to work and force the image back into correct aspect.
I've just stumbled upon this problem myself (my WYSIWIG editor adds dims to images by default - I needed a simple solution or I needed to spend hours hacking JCE to stop this behaviour) and haven't yet tested it exhaustively but it should give you a good starting point if you're having the same issue as me.
I don't know if there is a way to do this with just CSS. If you want to achieve something like this then you can use supersized
Alternatively, if you don't care about older browsers, you can look into the CSS3 background-size property. Specifically, I think that setting background-size: cover will do the trick.
Edit - I misunderstood. What you might actually want is background-size: contain, but the downside is that you probably will have to change your html markup, not just your css.
I think this A List Apart article may help you greatly, it discusses responsive images that adapt to their container, maintaining aspect ratio.
Essentially you just need to contain the <img> and specify dimensions for that container than apply max-width:100% to the <img> and it will adapt. Read the rest of the article for obligitary IE considerations (thankfully IE7+ supports it).
Setting only width or height doesn't always work, so alternatively you can set:
img {
max-width: 100%;
max-height: 100%;
}
BUT
it will not extend images over their original size
You can't do it like that. You can edit the image element's width and height attributes...
<!-- keeps width-height ratio -->
<img src="smiley.gif" alt="Smiley face" height="50" />
<!-- keeps width-height ratio -->
<img src="smiley.gif" alt="Smiley face" width="50" />
<!-- does not keep width-height ratio, unless your image is square -->
<img src="smiley.gif" alt="Smiley face" height="50" width="50" />
You can set the width and height to either pixels or percent. Note that you don't have to write px when using pixels, but you do have to write % when doing percentage. So you can do something like...
<img src="smiley.gif" alt="Smiley face" height="100%" width="100%" />
... but that will take 100% of the width and height of the parent element. So be sure you know what the parent element is and its dimensions.
An update to this in 2020. The css property object-fit can be used to display an image at 100% width and height without distorting it.
.wrapper {
height: 100px;
width: 100px;
border: 1px solid;
}
img {
width: 100%;
height: 100%;
}
.contain {
object-fit: contain;
}
.cover {
object-fit: cover;
}
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" />
</div>
↑ default, bad aspect ratio
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" class="contain" />
</div>
↑ <code>object-fit: contain;</code>
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" class="cover" />
</div>
↑ <code>object-fit: cover;</code>

How to place an image over another?

How to put an image over another bigger image, like on youtube, a play button is displayed on top of video thumbnail?
Make a semi-transparent PNG graphic with a "Play" symbol and the size you want (e.g. 240x320).
Let's say you named it "overlay.png", and let's say the YouTube-generated thumbnail is at http://img.ytimg.com/abcdefg/0.jpg
Now all you need in your code is this:
<a href="destination_of_your_link">
<img src="overlay.png" width="320" height="240" border="0"
style="background: url(http://img.ytimg.com/abcdefg/0.jpg) center center black;" />
</a>
As long as your target audience is not still using IE6, you should be safe.
I'm not sure that YouTube uses images for this effect, isn't it still the Flash player?
Anyhow, exactly how this is done depends very much on the design you want to achieve. Lets assume that you want to achieve the YouTube style, where you have a thumbnail image and want to overlay a play button image on top. If you want the thumbnail to be an actual <img> tag you will need some extra markup, like this:
<div class="thumb-wrapper">
<img src="mythumbnail.gif" alt="my awesome video" /><span></span>
</div>
The wrapper <div> is required so you can target the img and span correctly, and have dimensions to contain them in. The span is where the overlay image will go.
.thumb-wrapper {
position:relative;
}
.thumbwrapper span {
position:absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 100;
background: transparent url(overlay.png) no-repeat;
}
(I haven't actually tested this, if its blatently wrong let me know I'll revise it!)
This assumes a couple of things:
Your thumbnails will always be a fixed size and your overlay image matches that
Your overlay image is a semi-transparent PNG
You could also use the opacity: style to achieve #2. Of course, IE6 will rear it's ugly head and you'll need to use a PNG fix for it if going the transparent image route, or a separate opacity filter if using that method. Both of these are undoubtadly answered elsewhere on Stack Overflow or easily google-able.
If you have other requirements it might be possible to do this without the extra markup, as I said it all depends on what you need exactly. Some requirements may not be possible without JavaScript (which would of course mean you could inject any extra markup with that!).
You will find the solution in the following thread on StackOverflow:
How to draw a graphic over another graphic
Shortly (quoting after Ipsquiggle) :
<div style="position:relative">
<div>
<img url="backgroundimg.png">
</div>
<div style="position:absolute; left:0; top:0;">
<img url="smallgraphic.png">
</div>
</div>
More details why and how it works in the original thread.
If you have good control over image size, we have used the background to various elements - for example, set the background of a table cell to one image and put an img tab inside the cell.
Taking your example of youtube, you could very easily do this with 2 images and 1 img tag and a little bit of CSS of course ;)
<style>
img.youtube {
width:500px; height:500px;
margin:0; padding:0;
background:transparent url(/point/to/your/larger/image.jpg) no-repeat center
}
</style>
<img src="/point/to/youtube/play/image.png" alt="Gotta have alt text ;)" border="0" class="youtube" />
How it works is simple, you have the small youtube image as transparent PNG or GIF and then set the background image as the larger image, this will then give the effect of the smaller image being in the center with no extra markup.

Resources