Vertically aligning CSS :before and :after content [duplicate]
Asked Answered
T

10

143

I am trying to centre the link with the image, but can't seem to move the content vertically in any way.

<h4>More Information</h4>
<a href="#" class="pdf">File Name</a>

The icon is 22 x 22px

.pdf {
    font-size: 12px;
}
.pdf:before {
    padding:0 5px 0 0;
    content: url(../img/icon/pdf_small.png);
}
.pdf:after {
    content: " ( .pdf )";
    font-size: 10px;
}
.pdf:hover:after {
    color: #000;
}
Tertiary answered 14/5, 2010 at 9:22 Comment(3)
Consider using flex: https://mcmap.net/q/40457/-how-do-i-vertically-center-text-with-css-duplicate - the answer is for text but works on all elements.Gentlefolk
Thanks to CSS3's substring matching attribute selectors, you can now do a[href$=".pdf"] { … } and not even need the class.Baring
This seems to be the best answer for vertically centering content of :before/:after pseudo-elements: https://mcmap.net/q/161339/-vertically-centering-content-of-before-after-pseudo-elementsLattonia
T
165

Answered my own question after reading your advice on the vertical-align CSS attribute. Thanks for the tip!

.pdf:before {
    padding: 0 5px 0 0;
    content: url(../img/icon/pdf_small.png);
    vertical-align: -50%;
}
Tertiary answered 14/5, 2010 at 9:38 Comment(2)
Nice. What worked for me was vertical-align:super;Myrwyn
This vertical-align in % with negative values is awesome. Don't know before.Both
I
35

You can also use tables to accomplish this, like:

.pdf {
  display: table;
}
.pdf:before {
  display: table-cell;
  vertical-align: middle;
}

Here is an example: https://jsfiddle.net/ar9fadd0/2/

EDIT: You can also use flex to accomplish this:

.pdf {
  display: flex;
}
.pdf:before {
  display: flex;
  align-items: center;
}

Here is an example: https://jsfiddle.net/ctqk0xq1/1/

Infeasible answered 2/7, 2016 at 19:42 Comment(6)
neither of these fiddles work on Chrome 52Luben
both of them work for me on Chrome Version 52.0.2743.116 (64-bit) (Linux)Infeasible
neither works on OSX. imgur.com/bqUQ09XLuben
the question was about vertically aligning :before and :after elements and thats what the fiddles do, also in your screenshotInfeasible
"I am trying to centre the link with the image" that isn't done in either example or my screenshotLuben
Works as a charm nowadays. Used for a tiny icon that indicates a master-detail row in a table and aligns perfectly in the middle dynamically (resizing the window makes the <tr> element larger and smaller and the icon stays vertically centered (chrome))Eileneeilis
B
31

I'm no CSS expert, but what happens if you put vertical-align: middle; into your .pdf:before directive?

Binns answered 14/5, 2010 at 9:30 Comment(2)
Awesome, middle did not work so I had to use a negative percentage instead, thanks for the heads up!Tertiary
Glad to help. Did "middle" do nothing, or something-but-not-what-you-wanted?Binns
I
14

I think a cleaner approach is to inherit the vertical alignment:

In html:

<div class="shortcut"><a href="#">Download</a></div>

And in css:

.shortcut {
    vertical-align: middle;
}
.shortcut > a:after {
    vertical-align: inherit;
{

This way the icon will align properly in any resolution/font-size combination. Great for use with icon fonts.

Interviewer answered 2/4, 2013 at 8:38 Comment(1)
Perfect. Simple and elegantSolicitude
F
11

Using flexboxes did the trick for me:

.pdf:before {
    display: flex;
    align-items: center;
    justify-content: center;
}
Futurism answered 1/3, 2019 at 7:57 Comment(0)
K
8

This is what worked for me:

.pdf::before {
    content: url('path/to/image.png');
    display: flex;
    align-items: center;
    justify-content: center;
    height: inherit;
}
Karolynkaron answered 1/10, 2019 at 17:0 Comment(0)
T
6

Messing around with the line-height attribute should do the trick. I haven't tested this, so the exact value may not be right, but start with 1.5em, and tweak it in 0.1 increments until it lines up.

.pdf{ line-height:1.5em; }
Tori answered 14/5, 2010 at 9:35 Comment(1)
that should do the trick for text-content!Dimpledimwit
H
5

I spent a good amount of time trying to work this out today, and couldn't get things working using line-height or vertical-align. The easiest solution I was able to find was to set the <a/> to be relatively positioned so it would contain absolutes, and the :after to be positioned absolutely taking it out of the flow.

a{
    position:relative;
    padding-right:18px;
}
a:after{
    position:absolute;
    content:url(image.png);
}

The after image seemed to automatically center in that case, at least under Firefox/Chrome. Such may be a bit sloppier for browsers not supporting :after, due to the excess spacing on the <a/>.

Horsepowerhour answered 22/11, 2013 at 9:53 Comment(0)
M
4

I just found a pretty neat solution, I think. The trick is to set the line-height of image (or any content) height.

text

Using CSS:

div{
  line-height: 26px; /* height of the image in #submit span:after */
}

span:after{
    content: url('images/forward.png');
    vertical-align: bottom;
}

That would probably also work without the span.

Muscovite answered 28/7, 2012 at 11:26 Comment(0)
G
3

I had a similar problem. Here is what I did. Since the element I was trying to center vertically had height = 60px, I managed to center it vertically using:

top: calc(50% - 30px);

Goggle answered 2/8, 2017 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.