15

Well I've got the following problem: I need a dynamic solution (dont know the text, resulting font-size etc.) to typografically correctly align a drop cap. Correctly means: the cap-height-line of the drop cap should be the same as the cap height line of paragraph.

typografically correct aligned drop caps

Eg: Z Ž Ẑ should all align to their upper horizontal bar. While I've seen some (wrong) solutions to this problem (they align the overall height and therefore look terrible with accents, dieresis etc.), I've not seen any correct solution.

what I've managed to do this html/css

Does anyone know some?

PS: It could work, if I'd find some way to consistently align the baseline of the dropcap with the baseline of the 2nd line of the paragraph, because from there it could be done with a %-modifier of the font-size. Unfortunately, I also don't know how I could archive this.

Here is something to play with:

p.cap {
    text-indent: 0;
    font-size: 125%;
    line-height: 125%;
    text-align: justify;
}

p.cap:first-letter {
    display: inline-block;
    float: left;
    font-size: 230%;
}

http://jsfiddle.net/s856R/

Antony
  • 14,900
  • 10
  • 46
  • 74
rhavin
  • 1,512
  • 1
  • 12
  • 33
  • 1
    Maybe it would help if you provided some illustration of what you mean. I can't seem to get my head around what the problem is. Can you show some example code that shows the problem, and a mockup of what you want it to look like instead? – Mr Lister Dec 22 '13 at 22:19
  • http://jsfiddle.net/s856R/ Like this. Z in first and Ž in second ex. should have the same alignment to the cap-height-line of the following F. – rhavin Dec 22 '13 at 22:38
  • Hm, interesting. I think it would help if you put this in the question, and a screenshot of the effect. – Mr Lister Dec 22 '13 at 23:00
  • How disappointing that this question was asked in 2013 and there is no answer that truly satisfies. Drop caps are truly a cool effect. – davidrmcharles Sep 03 '18 at 23:24
  • Apparently, you can do this in Javascript. Since the OP specifically asked for an HTML/CSS solution, I'll just put it here: https://gist.github.com/FlorianBrinkmann/10b56b7c44ac8339dfae32b19e505875 – davidrmcharles Sep 04 '18 at 00:11

9 Answers9

3

The best answer to this is that – depending on the font-family, font-size, and line-height you end up using – it will require some fiddling with negative margins (gasp) to get just right. That said, I've got it looking pretty good in this fiddle:

http://jsfiddle.net/rafegoldberg/zohs9tna/5/

The trick is to reset your line-height so that it matches the size of the dropcap font, as opposed to inheriting the line-height of it's containing paragraph. So doing something like this will achieve a consistent top alignment:

p:first-letter {
    font-size: 230%;
    float: left;
    line-height: 1;
    display: inline-block;
}

This will result in something like this. (Sorry for the link to an image; I don't have enough rep. to post images!) But it's still imperfect since it's being aligned to the first line's extenders rather than the text-top. To fix this you'll need to adjust the dropcaps top margin; play around with it until you've nudged the dropcap in to alignment the text top, rather than the extender. You can use outline and outine-offset to get it pixel perfect!

This will likely cause the next line of text to drop down. If that happens, try adding a slight negative bottom margin to the dropcap. That should pull the line back up, and you'll be good to go! Your CSS would look exactly like the above, but with this additional line:

p:first-letter {
    /* ... */
    margin: .1em .25em -.5em;
}

With that addition things should now look like this. (PS: I've added some margins to the left and right sides of the dropcap as I think you get a much better looking result!)

Again, this is just something that requires fiddling around with to get perfect. But once you've got it working with your specific font properties (family, size, line-height, etc.) it should work consistently. Hope that helps; cheers!

Rafe Goldberg
  • 156
  • 2
  • 10
2

I tested the following code in Chrome, IE10 and Firefox on Windows 7:

p.cap {
    line-height: 1.4em;
}

p.cap:first-letter {
    font-size: 2.8em;
    float: left;
    margin-top: 0.25em;
}

(Note that I'm using em instead of percent here and that the size of the drop cap is double that of the paragraph line-height.)

It seems that the culprit is float in Firefox. It displays nice in Chrome and Internet Explorer, but in Firefox using float on the first character seems to disconnect it from the baseline of the rest of the line. I can delete float: left; and add vertical-align: -100%; to get the baseline to match in all browsers, but then the line-height gets messed up and the drop-cap doesn't float so it's not a solution.

The only solution seems to be to put a span around the first letter and use that instead. Like so:

<p class="cap"><span class="dropcap">Ž</span>ed Fhi GaFshF s in GfsF Fhl kfhlkshG glkHjha slkgh ka KFhl skh glkSdsfg d HH Gkhaskg hsHöAKH Hköah skhHaSÖK G hih h G h IGU</p>
<p class="cap"><span class="dropcap">Z</span>as Fhi GaFshF s in GfsF Fhl kfhlkshG glkHjha   slkgh ka KFhl sh glkSdsfg d HH Gkhaskg hsHöAKH Hköah skhHaSÖK G hih h G h IGU</p>

and:

p.cap .dropcap {
    float: left;
    font-size: 2.8em;
    margin-top: 0.25em;
}

This seems to keep the baseline and displays nicely in Firefox as well, but writing those tags dynamically will naturally require PHP or JavaScript or similar. If that's not an option you will probably not be able to get good results in Firefox. Unfortunately.

Szandor
  • 363
  • 1
  • 12
1

Consistent dropcap in All browsers and tested on iOS as well. Solved problem: The dropcap in Firefox :first-letter as float left will loose the lineheight and makes the letter sup-styled. You can avoid this by:

  1. Add padding-top and padding-bottom with an equal fixed value.
  2. Set the font-size
  3. Set the line-height as the fontsize value minus padding-top and padding-bottom value
  4. Opt Adjust the margin-top with negative (or positive) values
  5. Opt Adjust the text bottom wrap with negative margin-bottom value.

This example makes a perfect "Typographic dropcap"1 with the basefont Arial, 12px as the paragraph, and with 16px line-height. The whole textblock has a 10px margin-top in my test.

1Use the character "V" as dropcap followed by a "i" character. The "i-dot" should match the correct typographic top alignment. (Of couse not consistant in all devices/ font-families but a good reference point).

/* Dropcap */

 p.dropcap:first-letter {
 padding-top: 5px; 
 padding-bottom: 5px; 
 margin-top: -1px; 
 margin-right: 7px; 
 margin-bottom: -3px; 
 line-height: 24px; 
 float: left; 
 color: #777667; 
 font-family: Arial, Georgia, open sans; 
 font-size: 34px; 
 font-weight: 600; 
 text-transform: uppercase; 
}

Hope thats helps in your stylesheet contexts.

Sam
  • 15,254
  • 25
  • 90
  • 145
Jonas Lundman
  • 1,390
  • 16
  • 18
0

See your updated fiddle :

jsFiddle

Try this :

p.cap {
     text-indent:0; font-size:125%; line-height:125%;
     text-align:justify;
 }

p.cap:first-letter {
     display:inline-block; float:left; font-size:280%;margin-top:15px
}
Nishchit
  • 18,284
  • 12
  • 54
  • 81
0
p.cap_push_it_down:first-letter {
    display:inline-block; 
    float:left; font-size:230%;
    padding-top:14px; //note this

}

i think you should give some different class name to paragraphs starting with letters like Ž and specify their styles like in above shown code...

also, can you elaborate a bit more those "wrong solutions" ??

Amrullah Zunzunia
  • 1,617
  • 16
  • 31
0

Try this - define a Font witch suts your requirements...

body 
{font-family: "times"};
p.cap {
    text-indent:0; font-size:125%; line-height:125%;
    text-align:justify;
}

p.cap:first-letter {
    display:inline-block; float:left; font-size:280%;margin-top:-6px
ratmalwer
  • 700
  • 5
  • 14
0

With a little help from jquery (thanks foxybagga) I somehow achieved it.

This

$("#container p").each(function () {
    var text = $(this).html();
    var first = $('<span>' + text.charAt(0) + '</span>').addClass('caps');
    $(this).html(text.substring(1)).prepend(first);
}); 

wraps the first letter with a <span class="caps"> tag. The class has just a couple lines more than your p.cap:first-letter class, but does the job.

.caps {
    display:inline-block;
    float:left;
    font-size:230%;
    line-height:100%;
    margin-top:-2px;
    padding-right:2px;
}

please note: using these css rules with your p.cap:first-letter class doesn't give the same result.

jsfiddle

Community
  • 1
  • 1
0

Here is one way to the result: http://jsfiddle.net/picbig/s856R/38/

p.cap {
    text-indent:0; font-size:125%; line-height:125%;
    text-align:justify;
}

p.cap:first-letter {
    float: left; font-size:230%;

}

p.cap:first-child:first-letter{
    margin-top: -5px;
}
p.cap:last-child:first-letter{
    margin-top: 2px;
}

A: Targeting each p:first-letter indivually with double pseudo :first-child:first-letter{} and set margins on them

B: No need for display: inline-block on p.cap:first-letter

Max Width
  • 113
  • 2
  • 6
0

Giving the first letter a line-height of 100% works for me, regardless of the font size of either the normal text or the drop cap:

p.cap {
    text-indent:0; font-size:125%; line-height:125%;
    text-align:justify;
}

p.cap:first-letter {
    position: relative; float:left; font-size:200%; line-height: 100%;
}

Updated fiddle: http://jsfiddle.net/g11v61sc/

skybondsor
  • 747
  • 10
  • 21