CSS :first-letter not working
I'm trying to apply CSS styles to some HTML snippets that were generated from a Microsoft Word document. The HTML that Word generated is fairly atrocious, and includes a lot of inline styles. It goes something like this:
<html>
<head></head>
<body>
<center>
<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:12.0pt;line-height:115%;font-family:"Times New Roman"'>Title text goes here<o:p></o:p></span></b></p>
<p class=MsoNormal style='margin-left:18.0pt;line-height:150%'><span
style='font-size:12.0pt;line-height:150%;font-family:"Times New Roman"'>Content text goes here.<o:p></o:p></span></p>
</body>
</html>
...and very simply, I would like to style the first letter of the title section. It just needs to be larger and in a different font. To do this I am trying to use the :first-letter
selector, with something kind of like:
p b span:first-letter {
font-size: 500px !important;
}
But it doesn't seem to be working. Here's a fiddle demonstrating this:
http://jsfiddle.net/KvGr2/
Any ideas what is wrong/how to get the first letter of the title section styled correctly? I can make minor changes to the markup (like adding a wrapper div around things), though not without some difficulty.
Solution 1:
::first-letter
does not work on inline elements such as a span
. ::first-letter
works on block elements such as a paragraph, table caption, table cell, list item, or those with their display
property set to inline-block
.
Therefore it's better to apply ::first-letter
to a p
instead of a span
.
p::first-letter {font-size: 500px;}
or if you want a ::first-letter
selector in a span
then write it like this:
p b span::first-letter {font-size: 500px !important;}
span {display:block}
MDN provides the rationale for this non-obvious behaviour:
The
::first-letter
CSS pseudo-element selects the first letter of the first line of a block, if it is not preceded by any other content (such as images or inline tables) on its line....
A first line has only meaning in a block-container box, therefore the
::first-letter
pseudo-element has only an effect on elements with adisplay
value ofblock
,inline-block
,table-cell
,list-item
ortable-caption
. In all other cases,::first-letter
has no effect.
Another odd case(apart from not working on inline items) is if you use :before
the :first-letter
will apply to the before not the actual first letter see codepen
Examples
- http://jsfiddle.net/sandeep/KvGr2/9/
- http://krijnhoetmer.nl/stuff/css/first-letter-inline-block/
References
https://developer.mozilla.org/en-US/docs/Web/CSS/::first-letter http://reference.sitepoint.com/css/pseudoelement-firstletter
Solution 2:
You can get the intended behavior by setting the span's display property to inline-block:
.heading span {
display: inline-block;
}
.heading span:first-letter {
color: red;
}
<div class="heading">
<span>An</span>
<span>Interesting</span>
<span>Heading</span>
</div>
Solution 3:
This is because :first-letter
only operates on block / inline-block elements. SPAN
is an inline element.
Taken from http://reference.sitepoint.com/css/pseudoelement-firstletter:
The :first-letter pseudo-element is mainly used for creating common typographical effects like drop caps. This pseudo-element represents the first character of the first formatted line of text in a block-level element, an inline block, a table caption, a table cell, or a list item.