127

I have a CSS class Modal which is absolutely positioned, z-indexed above it's parent, and nicely positioned with JQuery. I want to add a caret image (^) to the top of the modal box and was looking at using the :before CSS pseudo selector to do this cleanly.

The image needs to be absolutely positioned and z-indexed above the modal, but I haven't found any way to add the appropriate class to the image in the content attribute:

.Modal:before{
  content:url('blackCarrot.png') /* with class ModalCarrot ??*/
}

.ModalCarrot{
   position:absolute;
   left:50%;
   margin-left:-8px;
   top:-16px;
}

Second best option- can I add the styles inline in the content attribute?

BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
RSG
  • 6,555
  • 6
  • 31
  • 50

4 Answers4

187

http://caniuse.com/#search=::after

::after and ::before with content are better to use as they're supported in every major browser other than Internet Explorer at least 5 versions back. Internet Explorer has complete support in version 9+ and partial support in version 8.

Is this what you're looking for?

.Modal::after{
  content:url('blackCarrot.png'); /* with class ModalCarrot ??*/
  position:relative; /*or absolute*/
  z-index:100000; /*a number that's more than the modal box*/
  left:-50px;
  top:10px;
}

.ModalCarrot{
   position:absolute;
   left:50%;
   margin-left:-8px;
   top:-16px;
}

If not, can you explain a little better?

or you could use jQuery, like Joshua said:

$(".Modal").before("<img src='blackCarrot.png' class='ModalCarrot' />");

android.nick
  • 10,260
  • 22
  • 70
  • 111
  • 3
    This. Joshua's point about browser compatibility is also right though- IE8 renders the image in the :after content, but won't render the parts of it which are outside the parent's border. – RSG Jul 26 '11 at 16:35
  • Now (in 2017), IE 11 is the only version of IE still supported by Microsoft; so, there is not much point in worrying about IE8 compatability. Also, a CSS solution is almost always better than the jQuery solution because they tend to load much faster and jQuery can cause screen flicker by rewriting your layout after the page is loaded. – Nosajimiki Mar 28 '17 at 14:09
  • 1
    @Nosajimiki whether or not you should worry about older browsers depends mostly on your visitors. – Jose Faeti Apr 23 '18 at 06:36
42

You should use the background attribute to give an image to that element, and I would use ::after instead of before, this way it should be already drawn on top of your element.

.Modal:before{
  content: '';
  background:url('blackCarrot.png');
  width: /* width of the image */;
  height: /* height of the image */;
  display: block;
}
Jose Faeti
  • 11,379
  • 5
  • 37
  • 52
  • Thanks for the suggestion- the modal has a border so I don't think I can use background image to position the carrot image above the border / bg color as needed. – RSG Jul 12 '11 at 17:51
  • Why not? if you absolutely position that pseudo element you can move it around with margins. It will be drawn on top of the other element borders and/or bg color. – Jose Faeti Jul 12 '11 at 17:54
  • The background image cannot extend outside the border of the div? – RSG Jul 12 '11 at 19:33
  • 14
    You probably need to add a content:''; to this to make it appear – Willster Sep 02 '14 at 15:17
15

1.this is my answer for your problem.

.ModalCarrot::before {
content:'';
background: url('blackCarrot.png'); /*url of image*/
height: 16px; /*height of image*/
width: 33px;  /*width of image*/
position: absolute;
}
EvilDr
  • 7,561
  • 10
  • 60
  • 114
hoang thao
  • 151
  • 1
  • 2
-4

Content and before are both highly unreliable across browsers. I would suggest sticking with jQuery to accomplish this. I'm not sure what you're doing to figure out if this carrot needs to be added or not, but you should get the overall idea:

$(".Modal").before("<img src='blackCarrot.png' class='ModalCarrot' />");
Joshua
  • 480
  • 4
  • 13
  • 1
    This makes me sad. We've got a mercifully limited set of targetted browsers, so I'm still interested in what's possible with CSS. – RSG Jul 12 '11 at 17:52
  • Even with content being heavily used in CSS3, from what I've seen it's still one of those that aren't fully supported anywhere. I believe this has to do with some fear of being able to inject evil things. Also, I believe content needs an already existing element to inject to - not sure if I can manipulate the DOM that much on it's own. – Joshua Jul 12 '11 at 18:10
  • 4
    This answer is wrong about it having unreliable support across browsers. `Content` and `after/before` are very reliable across every single major browser, it's worked since ie8, at least FF3.5, at least Chrome 9, at least Opera 10.6, at least Safari 3.2, every version of iOS Safari, every version of Opera mini, every version of Opera Mobile, and ever version of the Android browser. if you wanna know if something is supported cross-browser, check out: http://caniuse.com/#search=:after – android.nick Jul 25 '11 at 09:42
  • Just because the internet says it is, doesn't mean it's true. Work with them, they act differently in every browser. And IE 7 is still a very popular browser, which does not support either of them. – Joshua Jul 25 '11 at 14:39
  • 3
    Actually, you are better off with `CSS` over `JavaScript` on this one. No matter how bleeding edge the browser is, the user can still have `JavaScript` disabled... Luckily in this case the `:before` and `:after` selectors are widely supported; http://www.quirksmode.org/css/selectors/ – Steve Buzonas Feb 27 '14 at 20:47