Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center a Pseudo Element

First time really using the pseudo :after selector. Not sure if the problem I'm running into is a limitation of it or I'm just missing something obvious.

Here's my live code.

li.current:after {     border-width: 1px 1px 0 0;     content: ' ';     background: #256f9e;     display: block;     height: 13px;     position: absolute;     width: 10px;     top: 6;     margin:0px auto;     z-index: 99;     transform: rotate(-224deg);     -webkit-transform: rotate(-224deg);     -moz-transform: rotate(-224deg);     -ms-transform: rotate(-224deg);     -o-transform: rotate(-224deg);     transform-origin: 50% 50%;     -webkit-transform-origin: 50% 50%;     -moz-transform-origin: 50% 50%;     -ms-transform-origin: 50% 50%;     -o-transform-origin: 50% 50%;     text-align: center;     float: center; } 

I've created a little triangle (Or rather a box that has been rotated to look like a triangle). I want it centered within the <li></li> but can't figure it out using my normal methods. The things that have failed (in no particular order):

text-align: center; float: center; margin: 0 auto; margin-right: 0; margin-left: 0; 

What am I missing? I doubt it matters, but I'm using AngularJS. Thought I'd mention it in case there is a known conflict between Angular & Pseudo selectors (which I doubt). Thanks.

like image 843
EnigmaRM Avatar asked May 29 '13 16:05

EnigmaRM


People also ask

How do you center pseudo elements?

In this snippet, we will try centering a text within the CSS :before pseudo-element thus making the text to be in the middle of the <span> element. You need to position the :before pseudo-element absolutely by using the well known centering technique (use the top, left, and transform properties).

How do you center an A in a div?

You can do this by setting the display property to “flex.” Then define the align-items and justify-content property to “center.” This will tell the browser to center the flex item (the div within the div) vertically and horizontally.

How do you center an element in CSS?

To just center the text inside an element, use text-align: center; This text is centered.

How do you center a form of an element?

To centre block elements (such as divs and forms and paragraphs), give it a width and set margin-right and margin-left to auto.


1 Answers

The issue is your use of absolute positioning & the method you're using to try and center it. If you position an element absolutely, the ol' margin: 0 auto; method won't work to center the thing. I point you to an explanation as to why this is at the end of the question, but in case you just want this to work let's get to the solution first.

Here's some working code. View it on JSFiddle

#tool-menu li {   ...   position: relative; }  li.current:after {   ...   position: absolute;   width: 10px;   top: 6;   left: 50%;   margin-left: -5px; } 

Let's break down what's going on here.

Setting up a new Containing Block

In your original Fiddle, the pseudoelement is positioned absolutely relative to the viewport. An example might be the best way to show what this means, and why we don't want this. Consider setting it to top: 0. This would keep it latched to the top of the browser window (or, in this case, the JSFiddle frame), rather than the parent (the li). So, if our menu happened to be at the bottom of the page, or even moving around, the pseudoelement would be floating independent from it, stuck to the top of the page.

This is the default behavior of an absolutely positioned element when you don't explicitly set the position on any parent elements. What we want is to have its position defined relative to the parent. If we do this then the pseudoelement sticks with the parent, no matter where it happens to be.

To make this happen, you need to set the parent, #tool-menu li, to be explicitly positioned (which means setting it to be anything other than position: static). If you choose to use position: relative;, it won't change the computed location of the parent on the page, and does the thing we want. So that's why I used that one.

In technical terms, what we're doing here is creating a new containing block for the child.

Positioning the Pseudoelement

Now that our absolute positioning will be determined in relation to the parent, we can take advantage of the fact that we can use percentages to define where to place the child. In this case, you want it centered, so I set it be left: 50%.

If you do just this, though, you'll see that this lines up the left edge of the pseudoelement at 50%. This isn't what we want – we want the center of the pseudoelement to be at the middle. And that's why I added the negative margin-left. This scoots it over a bit to line the middle up with the center of the parent.

And once we do that, it's centered! Brilliance!

Why didn't my margin: auto; work?

The auto value of a margin is calculated from a fairly complex algorithm. At times, it computes to 0. I know from experience that this is one such instance of that happening, though I haven't yet traced my way through the algorithm to see exactly why. If you'd like to run through it, take a look at the spec most browsers have most likely implemented.

like image 170
jamesplease Avatar answered Nov 06 '22 22:11

jamesplease