Open Bug 1223880 Opened 9 years ago Updated 11 months ago

Implement initial-letter (from CSS Inline Layout Module Level 3)

Categories

(Core :: Layout: Block and Inline, enhancement, P3)

enhancement

Tracking

()

People

(Reporter: jensimmons, Unassigned)

References

(Depends on 3 open bugs, Blocks 3 open bugs, )

Details

(Keywords: dev-doc-needed, DevAdvocacy, feature, Whiteboard: [DevRel:P1][Behind pref layout.css.initial-letter.enabled][layout:backlog])

Attachments

(5 files, 11 obsolete files)

503 bytes, text/html
Details
913 bytes, text/html
Details
1.54 KB, text/html
Details
1.38 KB, text/html
Details
1.89 KB, text/html
Details
First-letter has always been hard to put to good use. Initial-letter is a replacement for the same use-case — the desire by Authors to create a drop cap. 

Yummy.

It recently shipped in Safari 9.
My apologies if this is a dup, or if I've filed this incorrectly. Blame it on my n00b status. ;)
Summary: Implement initial-letter, aka CSS Inline Layout Module Level 3 → Implement initial-letter (from CSS Inline Layout Module Level 3)
If no one is actively working on this, I'm interested in giving it a try.
I think it's probably a good idea to work on at least one or two smaller bugs in layout code before attempting this (which is larger).  I can help provide suggestions if you'd like (although we should keep that discussion out of this bug).
An update on this property in the wild -- Safari is the only browser that has implemented Initial Letter thus far. Their current implementation has a critical bug that blocks adoption. The first line of text does not wrap when it should, and sticks out beyond the content box. You can see the problem in the screenshot here: http://labs.jensimmons.com/examples/images/initial-letter-bug.png

Their bug was reported in Aug 2015, https://bugs.webkit.org/show_bug.cgi?id=147977, and was fixed in Webkit in October 2015. The fix has yet not been committed to the shipping version of Safari. When Apple released Safari 9.1 today, they sadly did not ship the fix. 

You can test a simple demo of Initial Letter here: http://labs.jensimmons.com/examples/initial-letter.html

I have begun teaching this property, and designers are excited about it. As soon as one browser has a working implementation, authors will be able to start using it. Feature Queries give us a great way to progressively enhance sites.
Assignee: nobody → jeremychen
Whiteboard: [DevRel:P1]
Per spec https://drafts.csswg.org/css-inline/#initial-letter-styling, there are 3 properties related to initial-letter: 1) initial-letter, 2) initial-letter-align, and 3) initial-letter-wrap.

Safari is the only browser that has implemented 1). Whereas 2) and 3) are not implemented by any other browser, I would like to start implementing 1) in this bug.

Hi dbaron, I'm wondering if this bug is only about implementing 1), the initial-letter property? If so, at the moment, do you think I should file bugs for 2) and 3), and also file a meta bug to track these 3 all?
Flags: needinfo?(dbaron)
Status: NEW → ASSIGNED
An update to my comment 5 above: Apple has fixed their bug in Safari Technical Preview, but has not yet shipped it into the main channel. However, there is a workaround for this bug, and authors can use it on production websites today. They don't have to wait.

I've got examples of the initial-letter property in action, the bug, and the bug fix here: http://labs.jensimmons.com.
Attachment #8750649 - Attachment mime type: text/plain → text/html
(In reply to Jeremy Chen [:jeremychen] UTC+8 from comment #6)
> Per spec https://drafts.csswg.org/css-inline/#initial-letter-styling, there
> are 3 properties related to initial-letter: 1) initial-letter, 2)
> initial-letter-align, and 3) initial-letter-wrap.
> 
> Safari is the only browser that has implemented 1). Whereas 2) and 3) are
> not implemented by any other browser, I would like to start implementing 1)
> in this bug.
> 
> Hi dbaron, I'm wondering if this bug is only about implementing 1), the
> initial-letter property? If so, at the moment, do you think I should file
> bugs for 2) and 3), and also file a meta bug to track these 3 all?

Filed bug 1273019, bug 1273021, bug 1273022.
Flags: needinfo?(dbaron)
Attached file basic functional test (ref: spec) (obsolete) —
Attachment #8750649 - Attachment is obsolete: true
Attachment #8754697 - Attachment is obsolete: true
Attachment #8754698 - Attachment is obsolete: true
Attachment #8754699 - Attachment is obsolete: true
Flags: platform-rel?
platform-rel: --- → ?
Comment on attachment 8761133 [details] [diff] [review]
(wip) render initial-letter property.

Got many great feedbacks from an offline meetup.
This patch may not be in the right direction, so obsolete this first.
Attachment #8761133 - Attachment is obsolete: true
Update this w/ -webkit-initial-letter as an alternative. In this way, it would be easier to verify the implementation progress on webkit.
Attachment #8752675 - Attachment is obsolete: true
Attachment #8768316 - Attachment description: basic functional test (ref: example 1 in spec) → testcase - basic test (ref: example 1 in spec)
Attachment #8770472 - Attachment description: testcase - clearing initial letters part3 (floats in the opposite side) → testcase - clearing initial letters part4 (floats in the opposite side)
Attachment #8769547 - Attachment description: testcase - clearing initial letters part2 → testcase - clearing initial letters part2 (short paragraph)
Attachment #8769546 - Attachment description: testcase - clearing initial letters part1 → testcase - clearing initial letters part1 (raised and sunken caps)
At present, Safari is still the only browser that has implemented initial-letter property. So, I did some study about how far does Safari has implemented. Here are some things specified in the spec. but haven't done (or done wrong) in Safari:

1) Per spec.[1], the initial-letter property should be able to apply to ::first-letter pseudo-elements and inline-level first child of a block container; however, it only applies to ::first-letter so far.
2) The first argument of initial-letter could only support integral type in Safari, whereas it should accept any non-negative numbers according to spec.[1].
3) Open [2] through the latest WebKit-Nightly (OSX 10.11.5), a float DOES NOT clear its previous initial-letter while floating to the same side, whereas the float should do clear the initial-letter according to spec.[3].

As to 2), the first argument of initial-letter, I think we could make it accept non-negative numbers. Actually, I already written part1 patch according to the spec. The size calculation is specified pretty clearly in [4]. As to 3), I think we should probably do it right while implementing initial-letter.

As to 1), to apply initial-letter to inline-level first child of a block container is of course more complicated. It means supporting alternative text of an image element [5], and supporting multi-line effect of long initial-letters [6].

Therefore, my question is, do we want to ship this once our implementation can support first-letter? Or, we prefer to ship this until we can make initial-letter apply to both first-letter and inline-level first child of a block container?


[1] https://drafts.csswg.org/css-inline/#sizing-drop-initials
[2] https://bug1223880.bmoattachments.org/attachment.cgi?id=8770471
[3] https://drafts.csswg.org/css-inline/#initial-letter-floats
[4] https://drafts.csswg.org/css-inline/#sizing-initial-letters
[5] https://bug1223880.bmoattachments.org/attachment.cgi?id=8768316
[6] https://drafts.csswg.org/css-inline/#initial-letter-indentation
Flags: needinfo?(dbaron)
(In reply to Jeremy Chen [:jeremychen] UTC+8 from comment #24)
> At present, Safari is still the only browser that has implemented
> initial-letter property. So, I did some study about how far does Safari has
> implemented. Here are some things specified in the spec. but haven't done
> (or done wrong) in Safari:
> 
> 1) Per spec.[1], the initial-letter property should be able to apply to
> ::first-letter pseudo-elements and inline-level first child of a block
> container; however, it only applies to ::first-letter so far.
> 2) The first argument of initial-letter could only support integral type in
> Safari, whereas it should accept any non-negative numbers according to
> spec.[1].
> 3) Open [2] through the latest WebKit-Nightly (OSX 10.11.5), a float DOES
> NOT clear its previous initial-letter while floating to the same side,
> whereas the float should do clear the initial-letter according to spec.[3].
> 
> As to 2), the first argument of initial-letter, I think we could make it
> accept non-negative numbers. Actually, I already written part1 patch
> according to the spec. The size calculation is specified pretty clearly in
> [4]. As to 3), I think we should probably do it right while implementing
> initial-letter.
> 
> As to 1), to apply initial-letter to inline-level first child of a block
> container is of course more complicated. It means supporting alternative
> text of an image element [5], and supporting multi-line effect of long
> initial-letters [6].
> 
> Therefore, my question is, do we want to ship this once our implementation
> can support first-letter? Or, we prefer to ship this until we can make
> initial-letter apply to both first-letter and inline-level first child of a
> block container?

Given that Safari shipped that way, I think it's OK shipping initially with support for only ::first-letter.  But it's also OK to ship with both.  It depends whether supporting inlines as well is a lot of extra work.

Doing (2) and (3) correctly sounds like the right thing to do.  Some of those may have been spec changes more recent than Safari's implementation.
Flags: needinfo?(dbaron)
(In reply to David Baron :dbaron: ⌚️UTC+2 (review requests must explain patch) from comment #25)
> Given that Safari shipped that way, I think it's OK shipping initially with
> support for only ::first-letter.  But it's also OK to ship with both.  It
> depends whether supporting inlines as well is a lot of extra work.
> 
> Doing (2) and (3) correctly sounds like the right thing to do.  Some of
> those may have been spec changes more recent than Safari's implementation.

Thank you. Start to work on rendering parts from today.
Separate the support of style system from this bug. File Bug 1289007 and obsolete related patches here.
Attachment #8752677 - Attachment is obsolete: true
Attachment #8752678 - Attachment is obsolete: true
Attached patch hack initial-letter size. (obsolete) — Splinter Review
MozReview-Commit-ID: KB1GFecmsbc
Comment on attachment 8777732 [details] [diff] [review]
hack initial-letter size.

Jonathan and I discussed about the possibility of implementing initial-letter's size argument by using text inflation during London All-hands. I've done a bit hacking and found that text inflation seems applies to all text frames pointing to the same textrun.

As to floating first-letter case, there's a separated textrun for it, so this patch could work.

As to non-floating first-letter case, there would be a textrun for the content including non-floating first-letter and the rest of the texts. So, this patch won't work since all the content could be affected. Moreover, the assertion in http://searchfox.org/mozilla-central/rev/740bb4ed16d070cf5d466231b30e80b9204aec54/layout/generic/nsTextFrame.cpp#8882 would be raised as well.

I'm not sure if forcing generate a separated textrun for non-floating first-letter is a solution. Of course, forcing first-letter with non-normal initial-letter property to be float might be another solution. But before I go further, I might need some advice.

Hi David, could you give me some pointers here? Are there some places I could dig into?
Attachment #8777732 - Flags: feedback?(dbaron)
Shouldn't it be easier to just give nsStyleFont::mFont.size a different value?
platform-rel: ? → ---
(In reply to Xidorn Quan [:xidorn] (UTC+10) from comment #30)
> Shouldn't it be easier to just give nsStyleFont::mFont.size a different
> value?

Thank you for the advice. I did some tests. (see the attached https://bugzilla.mozilla.org/attachment.cgi?id=8778139&action=diff)

Seems that give nsStyleFont::mFont.size a different value at computing time is not possible. The reason is that we can't guarantee font data would be recomputed all the time, since most of the time we could just use the values in the cache. I can only assure that we'll call ComputeFontData() if any font related property is set. But this is definitely not what we would expect.

However, if the font inflation is not the answer, mFont.size might be something worth to try I guess. I'm working on another patch to give nsStyleFont::mFont.size a different value. Since we can't do this in computing time, it would be much more complicated for sure. Complicated but doable I guess.

Clear the feedback request until I get more information.
Attachment #8777732 - Flags: feedback?(dbaron)
MozReview-Commit-ID: AtuY2UHCGaR
Attachment #8777732 - Attachment is obsolete: true
Attachment #8778139 - Attachment is obsolete: true
Comment on attachment 8779162 [details] [diff] [review]
(wip) hack initial-letter's size.

File Bug 1296561 for initial letter's size implementation.
Obsolete this wip here.
Attachment #8779162 - Attachment is obsolete: true
Priority: -- → P3
Whiteboard: [DevRel:P1] → [DevRel:P1][Behind pref layout.css.initial-letter.enabled]
Unassigning myself from the bug as I don't quite have time working on this at the moment... Anyone interested can pick it up.
Assignee: jeremychen → nobody
Status: ASSIGNED → NEW
Blocks: 290125
Type: defect → enhancement
Whiteboard: [DevRel:P1][Behind pref layout.css.initial-letter.enabled] → [DevRel:P1][Behind pref layout.css.initial-letter.enabled][layout:backlog]
Severity: normal → S3
Depends on: 1831683
You need to log in before you can comment on or make changes to this bug.