Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to position :before & :after pseudo-elements on top of each other?

What's the best way to position one pseudo-element directly on top of another pseudo-element?

Let's say I want to make a fancy "checkbox" appear next to label here:

label:before {    content: "\00a0";    color: #FFF;    height: 6px;    width: 6px;    display: inline-block;  }    label:after {    content: "\00a0";    height: 18px;    width: 18px;    display: inline-block;    background: #ebd196;    background-image: linear-gradient(top, #ebd196 4%, #e2b65d 5%, #ab8844 100%);  }
<input id="pretty"><label for="pretty">Label text</label>

What is the stacking order of the pseudo-elements? Does :before appear below or above :after- which is better suited to be the border, and which the fill?

And what is the best positioning to apply to label, label:before & label:after to get the proper positioning?

like image 798
Ila Avatar asked Oct 16 '13 23:10

Ila


People also ask

What is :: before and :: after?

Definition and UsageThe ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.

How do you use before and after pseudo elements?

CSS ::before and ::after pseudo-elements allow you to insert “content” before and after any non-replaced element (e.g. they work on a <div> but not an <input> ). This effectively allows you to show something on a web page that might not be present in the HTML content.

Why do we use :: before in CSS?

::before (:before) In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.

What can you do with the before pseudo-element?

The ::before pseudo-element can be used to insert some content before the content of an element.


2 Answers

:before (or ::before) is treated as the first child of the element it is being applied to, whilst :after (or ::after) is treated as the last child. Therefore, :after would naturally cover :before.

https://developer.mozilla.org/en-US/docs/Web/CSS/::before

https://developer.mozilla.org/en-US/docs/Web/CSS/::after

I imagine the best way to make sure they line up would be to use position: relative; on label and position: absolute; on the pseudo-elements along with the same values for top, bottom etc.

If you wanted to make a gradient border using pseudo-elements then you could do something like this:

label {     position: relative;     display: inline-block;     padding: 0 2px;     margin: 2px; }  label:before {     content:"";     position: absolute;     top: 0;     left: 0;     z-index: -1;     width: 100%;     height: 100%;     background: white; }  label:after {     content:"";     position: absolute;     top: -2px;     bottom: -2px;     left: -2px;     right: -2px;     z-index: -2;     background: linear-gradient(to bottom, #1e5799 13%, #efe22f 79%); } 

http://jsfiddle.net/QqzJg/

You might find this useful:

http://css-tricks.com/examples/GradientBorder/

like image 111
Ben Jackson Avatar answered Sep 22 '22 09:09

Ben Jackson


Rather than position, add "vertical-align: middle" to :after and :before.

label {} label::before{vertical-align: middle;} label::after {vertical-align: middle;} 
like image 40
Cihangir Avatar answered Sep 22 '22 09:09

Cihangir