How to center text inside :before pseudo element?
The best thing would be to position the before
pseudo element absolutely with respect to the span
using the popular centering technique:
top: 0;
left: 50%;
transform: translate(-50%, -25px);
Note that -25px is to offset the text above the circles (which has height 25px) - see demo below:
span {
border-radius: 50%;
background-color: #d8d9dd;
border: 6px solid #262c40;
width: 25px;
height: 25px;
margin: 30px 0 0 40px;
display: block;
position:relative;
}
span:before {
content: attr(data-value);
position: absolute;
white-space: pre;
display: inline;
top: 0;
left: 50%;
transform: translate(-50%, -25px);
}
<span data-value="November 2016"></span>
<span data-value="May 2016"></span>
Vertically centering content of :before/:after pseudo-elements
Assuming your element is not an <img>
(because pseudo elements are not allowed on self-closing elements), let's suppose it's a <div>
, so a way could be:
div {
height: 100px ;
line-height: 100px;
}
div:before, div:after {
content: "";
...
display: inline-block;
vertical-align: middle;
height: ...;
line-height: normal;
}
If you cannot change the line-height of the div, another way is:
div {
position: relative;
}
div:before, div:after {
position: absolute;
display: block;
top: 50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
content: "";
width: ...
}
Otherwise, just place the indicators as a background in center position.
Center a Pseudo Element
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.
CSS how to vertically align text within a pseudo element
Easiest way? Add padding top. Little more difficult but better way, use flexbox.
These properties will do
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
text-align: center;
http://jsfiddle.net/6dqxt2r3/4/
centering a pseudo element
#a:after { content: "Text"; position: absolute; left: 50%; transform: translateX(-50%); color: red;}
<div style="width:100%;text-align:center;"> <p id="a">Text</p></div>
How to align pseudo element :before :after and span element
Just give vertical-align: middle;
to .x-btn-inner::before
to make it align proper.
.x-box-item { border: 1px solid black; width: 300px; height: 50px; position: absolute; right: auto; left: 0px; margin: 0px;}.x-btn-wrap { width: 100%; height: 100%; display: table;}.x-btn-button { text-align: center; vertical-align: middle; display: table-cell; white-space: nowrap;}.x-btn-inner { display: inline-block; vertical-align: middle; max-width: 100%;}.x-btn-inner:before { content: ''; width: 50px; height: 50px; background-image: url("https://gradschool.uoregon.edu/sites/gradschool1.uoregon.edu/files/facebook-like-icon-small.png"); display: inline-block; background-size: 50px 50px; vertical-align:middle;}
<a class="x-box-item" onClick="alert('Hello World!')"> <span class="x-btn-wrap"> <span class="x-btn-button"> <span class="x-btn-inner"> LIKE </span> </span> </span></a>
Vertically/horizontally centering a pseudo element's generated content
Since pseudo elements are essentially added as children elements, one option is to use a flexbox layout. Add display: flex
to the parent element, and then use align-items: center
for vertical centering and justify-content: center
for horizontal centering.
.block { height: 150px; width: 150px; border: 1px solid black; display: flex; align-items: center; justify-content: center;}.block:after { content: "content";}
<div class="block"></div>
Related Topics
Bootstrap 3 Multiselect Plugin as Form Element
How to Write a Media Query in CSS
How to Align The Radio Buttons Horizontally in Angular Material
Fixed Width Variable Height Grid CSS
Intellij Idea 11: How to Compile .CSS from .Less
Alternative to Inline-Block and Its Support with Current Browsers
Li: Before Content: "✔ "; Different Color on Some Mobile Devices
Positioning Content of an Iframe Within a Containing Div
Refinerycms 2.1.0 and Zurb 4 Top Menu with Dropdown Navigation
Overwriting Styles from Bootstrap in an Angular2 Component-Stylesheet
How to Put Bootstrap Validationmessagefor in Correct Position
Django: Bootstrap Cdn or Loading Bootstrap Files from Local Server
Svg as a CSS Background - How to Repeat-X with No Space in Between
How to Prevent Safari CSS Keyframe Animation Flicker
How to Play an Animation on Hover and Pause When Hover Is Not Active