45
votes

I am using the css pseudo elements :before and :after to give an indent-effect on some of my images on a website. However without specifying the width and height, these won't display. This would have me specifying a fixed width and height for each of the images, which I guess would work for a static webpage.

However because these images are generated dynamically with jQuery and are user submitted, images differ in width and height each time. Now I could probably can fix this with Javascript by getting the width from the image and passing it on to the :before, but this seems like it is too much work for something like this.

My question is if there is a way to do this with CSS only, to have the width of containing the image being passed on to the :before on this < li >, so that the :before and :after pseudo-elements inherit the width and height of the orginal element.

The basic page layout:

<ul>
   <li>
       <img src="foo" />
   </li>   
</ul>    

# css style simplefied
ul{ float:left; list-style:none}
li{float:left;}
li img{float:left}
li:before{
          content:"":
          position:relative;
          position:absolute;
          float:left;   
          box-shadow:0 1px 2px rgba(0,0,0,0.4);   

}

PS: compatibility needed is only for mobile Webkit browsers.

EDIT

I could for instance add lines to the CSS with Javascript by using the following lines:

var heightImg = (($('ul li:nth-child(n)').height())) + 'px';    
document.styleSheets[1].insertRule('ul li:before { height: ' +  heightImg+ '; }', 0);

But this would mean that I'll also have to work with dynamic id's. Which won't be hard, but I'm just wondering if there isn't a CSS only way.

4
Why do you specify position twice for li:before? - BoltClock♦
not understanding Q, this code (the double positioning aside) produces images in a horizontal line with no space between them, are you saying you want space between them? or are the images never horizontal in the mobile app, if that's the case why use float? then what do you mean by "indent of differing values", do you actually want the images to look centered.. sorry for dumb questions but really not getting what look you're trying to achieve ;) - perhaps an mocked up image of the required look - clairesuzy
Sorry for the confusion, With an indented look, I meant that I want to make the images sunk into the page, so I apply a box-shadow on the :before which overlaps the image and gives the image shadowing around the edges to make it appear like it is sunken into the page. - Marc Hoogvliet

4 Answers

77
votes

:before and :after pseudo-elements are inline boxes as much as I know. Therefore, using display: block; might help you.

5
votes
li{
    float:left;
    position:relative;
}
li img{
    float:left;
}
li:before{
    content:" ";
    position:absolute;
    width:100%;
    height:100%
    box-shadow:0 1px 2px rgba(0,0,0,0.4);
}
4
votes

it seems content:" ": is important along with display: block

1
votes

Try:

ul {
    position: relative;
}
li:before {
    content: '\00a0';
    display: block;
    float: left;
    position: absolute;
    height: 100%;
}

It's worked for me.