CSS - Vertical align text in absolute positioned paragraph
Solution 1
Get rid of the p tag. You already have it in a li anyway.
css
li {
position: relative;
float: left;
overflow: hidden;
}
img {
width: 100%;
height: 100%;
}
span {
background-color: rgba(0, 255, 0, .3);
position: absolute;
text-align:center;
width: 100%;
top:46%;
}
html
<ul>
<li><span>Lorem Ipsum</span><img src="http://www.placehold.it/300x200" /></li>
</ul>
Tested on window IE9 and Chrome.
Don't know if it was for the demo or not but if you want the red shade over the image make a class for a span tag then insert a new span with the class.
span.text {
background-color: rgba(0, 255, 0, .3);
position: absolute;
text-align:center;
width: 100%;
top:46%;
}
span.redshade {
background-color: rgba(255, 0, 0, .3);
width: 100%;
height: 100%;
<ul>
<li><span class="redshade"> </span><span class="text">Lorem Ipsum</span><img src="http://www.placehold.it/300x200" /></li>
</ul>
Solution 2
Without hard-coding an assumed height for the text or image, I (unfortunately) can't solve this in less than 3 layers:
- Establish absolute positioning
- Establish table layout
- Establish table-cell layout and vertical-align: middle
Combining 1 and 2 seems to prevent height: 100% from working for reasons unknown to me. I think the rejection of table-cell layout seems to be a misappropriation of the old "don't use tables for layouts" meme; CSS is for layout so this is not misusing the element semantics. (Although unfortunately it requires semantically meaningless divs.)
<ul>
<li>
<img src="http://www.placehold.it/300x200" />
<div class="absolute">
<div class="table">
<div class="middle">
<p><span>Lorem Ipsum</span>
</p>
</div>
</div>
</div>
</li>
</ul>
li {
position: relative;
float: left;
overflow: hidden;
}
img {
width: 100%;
}
.absolute, .table, .middle {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.absolute {
position: absolute;
}
.table {
display: table;
}
.middle {
display: table-cell;
vertical-align: middle;
}
p {
background-color: rgba(255, 0, 0, .3);
}
span {
background-color: rgba(0, 255, 0, .3);
}
http://jsfiddle.net/svachalek/vTGxx/4/
Sven
Updated on June 25, 2022Comments
-
Sven about 2 years
Before we start:
Please don't close this as a duplicate of another question. I just searched here on Stackoverflow without finding that exact case.The closest is I believe this question. Still, the replies given there don't really work for me, I believe because the paragraph is set
position: absolute;
.Thats the HTML:
<ul> <li><img src="http://www.placehold.it/300x200" /><p><span>Lorem Ipsum</span></p></li> </ul>
And the CSS:
li { position: relative; float: left; overflow: hidden; } img { width: 100%; vertical-align: middle; } p { background-color: rgba(255, 0, 0, .3); position: absolute; top: 0; left: 0; width: 100%; height: 100%; } span { background-color: rgba(0, 255, 0, .3); vertical-align: middle; }
Fiddle: http://jsfiddle.net/DpVjZ/
vertical-align: middle;
just bumps the text a tiny bit away from the top, but not really in the middle.
Setting the spanposition: absolute;
and then applyingtop: 50%;
and thenmargin-top: -x%;
won't work because the height of the span is not known as it is dynamic content.
Although the linked question states that this is bad practice, I also tried thedisplay: table-cell
approach without any result. Please help me. -
Sven over 11 yearsThanks! I like the way your solution delivers a great result and is easy to understand, too.
-
svachalek over 11 yearsThe top: 46% is hard-coding a guess about the height of the span; it is not centered for an arbitrary span.
-
1934286 over 11 years@svachalek Yes, it is a one-line-of-text solution. Multi-line solutions are much more complicated. It is centered for an arbitrary image size. It will also work were the span and image are known.
-
1934286 over 11 years@Sven Thanks for the selection.
-
1934286 over 11 years+1 This is a bit complicated but does account for unknown widths and heights. I edited your post to text-align:center the p tag and updated the fiddle and cleaned up the code.