CSS: using image sprites with css pseudo classes :before and :after - css

I have never tried that before. I created an image sprite that is contains two icons. Each icon is 26px wide and high. So the sprite is 26x52px.
I have an element that is either in a div.something or in a div.anything. Depending on which class it's in I want to add a corner cap to the left or right.
So therefore I'm positioning the .element relative, the apply the :before pseudoclass to the img and position it absolute with a height and width of 26px so only one icon of the sprite fits in. I also apply "overflow:hidden" in order to hide the second icon on the sprite.
.element {
position:relative;
}
.element:before{
content: url("../images/sprite.png");
position: absolute;
height:26px;
width:26px;
overflow:hidden;
}
.something .element:before {
top: -2px;
left: -2px;
}
anything .element:before {
top: -28px;
right: -2px;
}
This works fine for the left-corner where I use the first top icon in the sprite.
However now I wonder how I can show only the second icon in the sprite for the "anything .element".
So actually the "mask" should be positioned at -2px, -2px but the sprite img inside should start at -26px so the second icon is shown.
Is this possible with css the way I'm doing it right now?

Don't use content to insert your image, as you cannot modify its position. Instead, set the content to " " and add the sprite as a background image. You can then use the background-position property to move the sprite to the correct position. Otherwise your example should be working just fine.
A working demo:
http://jsfiddle.net/RvRxY/1/

Support for :before and :after pseudo elements on img tags is limited, if at all existent on most browsers.
The best solution would be to place your img inside a div, and then have the class applied to the actual div, rather than the img.
You almost have the usage for the pseudo element correct. You can give this a try:
.somediv { position:relative;}
.somediv:before {
position: absolute;
content: '';
height: 26px;
width: 26px;
top: 0;
}
.somediv.foo1:before {
background: url("../images/sprite.png") no-repeat -2px -2px;
left: 0;
}
.somediv.foo2:before {
background: url("../images/sprite.png") no-repeat -2px -28px;
right: 0;
}
Use the background:; property rather than the content:; property so that you can position the sprite within the :before pseudo element.
left:; right:; and top:; should be used for absolute positioning of the pseudo element relative to its parent (.somediv).
Placing a 1px border around your pseudo element will help you understand the different positioning :)

Related

CSS positioning of "before" element

I have a question about CSS positioning of :before element to a parent element.
Let's say I have a parent element div like a block of text with background and padding properties and I want to add a small image or icon to this div (e.g. in the right-top corner) and I want this small element to stay there even when resizing the window.
How can I achieve that? Here is a code for :before I tried:
.blure:before {
content: URL(/image.svg);
position: absolute;
margin-left: 73%;
margin-top: -14%;
}
After setting the absolute you can give the left, right, top, bottom properties to element
.blure:before{
content: URL(/image.svg);
display: absolute;
top: 15px;
right: 15px;
}

CSS Background image position moving to center on larger browser windows

I cannot get the orange background behind DONATE at the bottom of my page right to stay put in larger browser windows. I have tried every css trick I can find. Please help!
Thanks,
Janet
http://dev30.ncld.org/
You missed this trick then:
#footer .footer-col-orange {
margin-left: 790px; // adjust accordingly
left: initial;
}
This will keep your donate box relative to the footer element, and not to the left page border and will work on all displays.
The other option is to set the position of #footer .padding element to relative.
There you go :
#footer .padding {
/* padding: 15px 20px 0px 100px; */
width: 1010px;
/* position: absolute; */
margin-left: auto;
margin-right: auto;
background-color: #0A6DA1;
padding-top: 15px;
position: relative; /* First part */
}
#footer .footer-col-orange {
position: absolute;
/* background-position: right; */
right: -2em; /* second part, feel free to put what you want */
}
When you set a position: absolute; to an element, it will pull it out of the HTML flow, and you can give it coordinates (top, left, right; bottom). This coordinates are relative to the first parent with a relative position. As you didn't set any parent element to be the relative, you positioned your element relative to the document.
Your orange box is current positioned absolutely, as you know. This means that is is relative to the browser window. The left edge of that window, because you have `left:900px'. What we want is for it to be relative to the footer, which is centered.
To do this, we need to set the parent container of the orange box to position:relative. This will cause the orange box's position to depend on it's parent instead of the window.
#footer .padding {
position:relative;
}
Then, it's just a matter of setting the yellow box to the right position. Given that it's on the right side, I'd delete the left value entirely and set right:-45px instead.
#footer .footer-col-orange {
left:auto;
right:-45px
}
With these, it'll line up perfectly with the edge of the white box above:
You are going to run into an issue with inline styling. You not only have your styles applied by CSS, they are duplicated inline. You're going to either need to set !important in the new CSS that I've provided (not best practice), or better, remove the inline styling. If you provide some more information about how your side is built (WordPress, HTML template, etc) I can help with removing the inline styling.

CSS3 does ::after inherit the height and margin of the origin element in IE9?

I have this HTML:
<div class="demo">hello world</div>
and this CSS:
.demo { width: 100px;
height: 50px; margin-bottom: 50px;
background-color: red; position: relative;
z-index:-1;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorStr=#40ffffff,EndColorStr=#12ffffff);zoom: 1;}
.demo::after {
width: 95px;
height: 95px;
position: absolute; left: 0; top: 0; border: 5px solid blue; content:"";
background-color: yellow; opacity: .75;}
I wanted the pseudo element to completely cover the origin element (which contains a 50% gradient for IE7,8 - therefore height: 50%, margin-bottom: 50%;)
However in IE9... the ::after element only covers 50%, although I specifically set the height to be 44px. Is this because of the use of filter? Any idea how to override it?
Here is a JSBin of the example.
Thanks for help.
UPDATE
Here is an example of the whole thing:
Example
Notes:
see comments in the background.css file
I can't change the element structure or assign gradient to any other element than .ui-icon
The gradient should cover 50% of the footer. Footer is 44px so gradient stops at 22px
IE7+8 cannot do this (or color stops), so I making .ui-icon height 22px plus filter-gradient
using ::before I add the gradient for all other browsers sitting on top of .ui-icon
Problem 1 = IE9+ renders ::before - I use z-index:-1, so .ui-icon sits behind ::before = OK
Problem 2 = on IE9+ the ::before background is cut off by .ui-icon.
Question: How can I avoid the gradient in ::before being cut off?
Is this because of the use of filter? Any idea how to override it?
Yes, it's because of the filter. Using filter causes an overflow:hidden-esque effect.
You might be aware that :after is rendered inside the element, like this:
<div class="demo">hello world<div:after></div:after></div>
If you add overflow: hidden, then all browsers are equally broken: http://jsbin.com/otilux/3
So, how to fix it? One option is to use ::before to handle drawing the thing that has filter.
See: http://jsbin.com/otilux/4
That looks the same as it did before in Chrome/Firefox, and now also looks the same in IE9.
Due to using ::after instead of :after, I can see you're not trying to support IE8. So, another option would be to use an SVG gradient instead of filter.

Vertically positioning pseudo image element (CSS)

I am using a :before pseudo element to add a small image to a download link on my site. The height of the image is greater than the line height and the bottom of the image aligns with the bottom of the text.
How can I alter the vertical alignment of the pseudo element? Ideally so the center of the image aligns with the center of the text?
I find that this works in most cases, as long as the text and image aren't way out in scale:
#elem:before
{
content: url(image.png);
position: relative;
bottom: -.5ex;
margin-right: .5em;
}
The margin-right puts a little bit of space between the image and the text.
Make image inline elment, set line hegth to it and set vertical allign to container.
I couldn't find an elegant solution. Here is a jsFiddle with a working solution:
http://jsfiddle.net/rcravens/pAcDE/
Given the following element:
<div id='elem'>Bob Cravens</div>
I have this CSS:
#elem:before{
content: '';
height: 160px;
width: 136px;
background: url('http://bobcravens.com/Content/images/author_thumb.png');
position: absolute;
top: 0px;
left: 0px;
}
#elem{
background-color: red;
margin: 60px 136px;
}
The :before is probably what you have except for the 'position: absolute' style. Then I used a margin to offset the original div.
Hope this helps.
Bob

Can a background image be larger than the div itself?

I have a footer div with 100% width. It's about 50px high, depending on its content.
Is it possible to give that #footer a background image that kind of overflows this div?
The image is about 800x600px, and I want it to be positioned in the left bottom corner of the footer. It should work sort of like a background image for my website, but I've already set a background image on my body. I need another image positioned at the bottom left corner of my website and the #footer div would be perfect for that.
#footer {
clear: both;
width: 100%;
margin: 0;
padding: 30px 0 0;
background:#eee url(images/bodybgbottomleft.png) no-repeat left bottom fixed;
}
The image is set to the footer, however it doesn't overflow the div. Is it possible to make that happen?
overflow:visible doesn't do the job!
There is a very easy trick. Set padding of that div to a positive number and margin to negative
#wrapper {
background: url(xxx.jpeg);
padding-left: 10px;
margin-left: -10px;
}
I do not believe that you can make a background image overflow its div. Images placed in Image tags can overflow their parent div, but background images are limited by the div for which they are the background.
You can use a css3 psuedo element (:before and/or :after) as shown in this article
https://www.exratione.com/2011/09/how-to-overflow-a-background-image-using-css3/
Good Luck...
No, you can't.
But as a solid workaround, I would suggest to classify that first div as position:relative and use div::before to create an underlying element containing your image. Classified as position:absolute you can move it anywhere relative to your initial div.
Don't forget to add content to that new element. Here's some example:
div {
position: relative;
}
div::before {
content: ""; /* empty but necessary */
position: absolute;
background: ...
}
Note: if you want it to be 'on top' of the parent div, use div::after instead.
Using background-size cover worked for me.
#footer {
background-color: #eee;
background-image: url(images/bodybgbottomleft.png);
background-repeat: no-repeat;
background-size: cover;
clear: both;
width: 100%;
margin: 0;
padding: 30px 0 0;
}
Obviously be aware of support issues, check Can I Use: http://caniuse.com/#search=background-size
Use trasform: scale(1.1) property to make bg image bigger, move it up with position: relative; top: -10px;
<div class="home-hero">
<div class="home-hero__img"></div>
</div>
.home-hero__img{
position:relative;
top:-10px;
transform: scale(1.1);
background: {
size: contain;
image: url('image.svg');
}
}
You mention already having a background image on body.
You could set that background image on html, and the new one on body. This will of course depend upon your layout, but you wouldn't need to use your footer for it.
Not really - the background image is bounded by the element it's applied to, and the overflow properties only apply to the content (i.e. markup) within an element.
You can add another div into your footer div and apply the background image to that, though, and have that overflow instead.
This could help.
It requires the footer height to be a fixed number. Basically, you have a div inside the footer div with it's normal content, with position: absolute, and then the image with position: relative, a negative z-index so it stays "below" everything, and a negative top value of the footer's height minus the image height (in my example, 50px - 600px = -550px). Tested in Chrome 8, FireFox 3.6 and IE 9.

Resources