如何在HTML/CSS中正确对齐首字下沉?

15

我遇到了以下问题:我需要一种动态解决方案(不知道文本、结果字体大小等),以正确地排列首字下沉。正确的意思是:首字下沉的大写字母高度线应该与段落的大写字母高度线相同。

typografically correct aligned drop caps

例如:Z Ž Ẑ 应该都对齐到它们的上部水平线。虽然我见过一些(错误的)解决此问题的方法(它们对齐整体高度,因此在使用重音符号、分音符号等时看起来很糟糕),但我还没有见过任何正确的解决方案。

what I've managed to do this html/css

有人知道吗?

附注:如果我能找到一种方法来始终将首字下沉的基线与段落第二行的基线对齐,那么它可能有效,因为从那里可以通过字体大小的百分比修改器来完成。不幸的是,我也不知道如何实现这一点。

这里有一些可以玩的东西:

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/


1
也许如果您提供一些说明,会有所帮助。我似乎无法理解问题所在。您能否展示一些示例代码来展示问题,并提供一个您想要的外观模型? - Mr Lister
像这样。第一个字母Z和第二个字母Ž应该与后面的F的大写高度线对齐。http://jsfiddle.net/s856R/ - rhavin
嗯,有趣。我认为如果您将此放在问题中,并附上效果的截图,会更有帮助。 - Mr Lister
多么令人失望,这个问题在2013年就被提出了,但至今没有一个真正令人满意的答案。首字母大写确实是一种很酷的效果。 - davidrmcharles
显然,你可以用Javascript实现这个功能。由于OP明确要求HTML/CSS解决方案,我在这里提供一个链接:https://gist.github.com/FlorianBrinkmann/10b56b7c44ac8339dfae32b19e505875 - davidrmcharles
9个回答

3

最好的答案是,根据您使用的字体系列、字号和行高,它需要一些负边距的调整(哇),才能达到完美的效果。话虽如此,在这个示例中我已经让它看起来非常不错:

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

“关键是要重置行高,使其与首字母大写字体大小相匹配,而不是继承所在段落的行高。因此,做类似以下操作将实现一致的顶部对齐:”
p:first-letter {
    font-size: 230%;
    float: left;
    line-height: 1;
    display: inline-block;
}

这将导致类似于这样的结果。(抱歉,链接到图像;我没有足够的声望来发布图像!)但它仍然不完美,因为它被对齐到第一行的延伸符而不是文本顶部。要修复这个问题,您需要调整下沉字母的顶部边距;尝试调整它,直到您将其推向文本顶部而不是延伸符的对齐位置。您可以使用 outlineoutline-offset 来使其像素完美!

这可能会导致下一行文本向下移动。如果发生这种情况,请尝试向下沉字母添加略微负的底部边距。这应该将该行拉回,并且您就可以开始了!您的 CSS 将与上面完全相同,但是还有以下附加行:

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

加上这个后,现在应该看起来像这样。(附注:我在首字母大写字母的左右两侧添加了一些边距,因为我认为这样可以得到更好的效果!)

再次提醒,这需要一些调整才能完美地实现。但是一旦您使用特定的字体属性(族、大小、行高等)使其正常工作,它应该始终如一。希望这有所帮助;干杯!


2
我在Windows 7上的Chrome,IE10和Firefox中测试了以下代码:
p.cap {
    line-height: 1.4em;
}

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

(请注意,这里使用的是em而不是百分比,并且下沉字母的大小是段落行高的两倍。)
看起来罪魁祸首是Firefox中的float。它在Chrome和Internet Explorer中显示得很好,但在Firefox中,使用float在第一个字符上似乎会将其与其余行的基线断开连接。我可以删除float: left;并添加vertical-align: -100%;以使所有浏览器中的基线匹配,但这样会破坏行高并且下沉字母无法浮动,所以这不是一个解决方案。
唯一的解决方案似乎是在第一个字母周围放置一个标签并使用它。就像这样:
<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>

并且:

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

这似乎保持了基线并在Firefox中显示得很好,但动态编写这些标签自然需要PHP、JavaScript或类似的技术。如果这不是一个选项,你可能无法在Firefox中获得良好的结果。不幸的是。


1
在所有浏览器中保持一致的下沉字母效果,且已在iOS上测试通过。解决了问题:在Firefox中,使用“float left”的:first-letter会使字母失去行高并使其上标。您可以通过以下方式避免这种情况:
  1. 添加相等固定值的padding-top和padding-bottom。
  2. 设置字体大小
  3. 将行高设置为字体大小值减去padding-top和padding-bottom值
  4. 使用负(或正)值调整margin-top
  5. 使用负margin-bottom值调整文本底部包装。
此示例使用Arial字体,12px作为段落的基础字体,并具有16px的行高。在我的测试中,整个文本块的margin-top为10px。
使用字符“V”作为下沉字母,后跟一个“i”字符,即可创建完美的“印刷下沉字母”1。 “i-dot”应与正确的印刷顶部对齐。 (当然不是在所有设备/字体系列中都一致,但是是一个很好的参考点)。 1
/* 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; 
}

希望这对你的样式表有所帮助。

0

给首字母设置行高为100%对我来说很有效,无论普通文本或者下沉式大写字母的字体大小如何:

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%;
}

更新的 jsfiddle:http://jsfiddle.net/g11v61sc/


0

查看您更新后的代码片段:

jsFiddle

试一下这个:

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
}

顶部的Z仍然比底部的与文本对齐要低。 - Mr Lister
好的,谢谢你的尝试,但那看起来比原来的版本还要糟糕... :-Δ ^^ - rhavin

0
这里有一种方法可以得到结果: 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: 使用双重伪类:first-child:first-letter{}针对每个p:first-letter进行定位,并设置其边距。

B: p.cap:first-letter无需使用display: inline-block。


0

在jquery的帮助下(感谢foxybagga),我不知怎么做到了。

这个

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

使用 <span class="caps"> 标签包裹首字母。 这个类比你的 p.cap:first-letter 类多了几行代码,但是可以完成任务。

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

请注意:在您的 p.cap:first-letter 类中使用这些 CSS 规则不会产生相同的结果。

jsfiddle


0
p.cap_push_it_down:first-letter {
    display:inline-block; 
    float:left; font-size:230%;
    padding-top:14px; //note this

}

我认为你应该给以Ž字母开头的段落一些不同的类名,并像上面显示的代码一样指定它们的样式...

另外,你能详细说明一下那些“错误的解决方案”吗?


0

试试这个 - 定义一个适合你要求的字体...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接