Open Bug 125390 Opened 23 years ago Updated 2 years ago

CSS letter-spacing style extends after last letter of element with letter-spacing

Categories

(Core :: Layout: Text and Fonts, defect, P3)

defect

Tracking

()

Future

People

(Reporter: brad, Unassigned)

References

(Depends on 2 open bugs, )

Details

(Keywords: testcase)

Attachments

(2 files)

Given the following input: <html><h1>Bra<span style="letter-spacing: 1em">dl</span>ey</h1></html> With Mozilla 2002021203, I get "Brad l ey", whereas with IE6 I get "Brad ley". I believe that IE is the one that's right here. letter-spacing is the only way to really do proper character kerning, but this problem makes using it for this purpose difficult.
->Layout, although I'm not sure what the correct behavior really should be. This proposal is reasonable though, except it might do weird things if a single word has large letter spacing (which would be better if we put half the letter-spacing around each character).
Assignee: dbaron → attinasi
Component: Style System → Layout
Keywords: css1
QA Contact: ian → petersen
Mozilla is behaving properly, at least according to the CSS2 spec. Section 9.1 of the CSS2 specification says, "The visual formatting model does not specify all aspects of formatting (e.g., it does not specify a letter-spacing algorithm). Conforming user agents [p. 32] may behave differently for those formatting issues not covered by this specification." Unfortunately, Mozilla's current interpretation of the letter-spacing style attribute makes kerning letters difficult. For example, I don't know if it's possible to have the letters "To" in the word "Ton" kerned and have it display properly on both IE and Mozilla. In Mozilla, I'd apply the attribute to only the "T"; in IE, I'd apply it to "To".
Confirming in the Feb 25th build.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P3
Target Milestone: --- → Future
Whiteboard: [CSS1-5.4.2]
Reconfirmed using FizzillaCFM/2002070913. Setting All/All.
OS: Windows 2000 → All
Hardware: PC → All
Attached file Testcase
Keywords: testcase
Possible dup of/related to bug 102016 or bug 93168?
IMHO we should do the half-either-side option. It makes the most sense in scenarios such as this and with things like bidi.
Depends on: 102016
Since this isn't actually a violation of the CSS1 spec, removing keyword &etc.
Assignee: attinasi → font
Component: Layout → Layout: Fonts and Text
Keywords: css1
QA Contact: petersen → ian
Whiteboard: [CSS1-5.4.2]
proposal: letter spacing should always go after the letter (after in the BIDI-after sense). We should not add this space if: 1) the frame is the last frame in the line (LTR text) or the last frame in the line (RTL text) 2) the frame has right padding (LTR text) or left padding (RTL text) This fixes issues with right-alignment of spaced LTR text, and still gives web authors precise control over kerning on a per-letter basis if needed. However, it doesn't "fix" the original bug report, which I believe we render correctly.
after a lot of thought about this, I firmly believe that letter-spacing should apply ONLY to 2 or more letters within a given span, ignoring both the preceding and trailing ends. setting a letter-spacing property on a single letter should have no effect. if you think about it, this is how normal text is treated. a single letter has no spacing set to it. placed within a cell, it's edges will rest flush against the cells edges. if you place a char next to it, then the 2 chars together will have a space between them. this is the spacing that you would be increasing and/or decreasing. not a "trailing space" type of spacing, not a "half amount on either side", and no allowing letter-spacing on a single letter, which leads to HORRIFIC cases of trying to resolve conflicts between differing adjacent values set on single letters or even spans of letters. this is a perfectly logical and common sense solution to the problem. here are some examples: &lt;span style="letter-spacing:1em"&gt;a&lt;/span&gt;&lt;span style="letter-spacing:1em"&gt;b&lt;/span&gt; should be ignored, resulting in "ab" as per normal display. &lt;span style="letter-spacing:1em"&gt;ab&lt;/span&gt;&lt;span style="letter-spacing:1em"&gt;cd&lt;/span&gt; should result in "a bc d", as the spacing WITHIN EACH SPAN is set to set a 1em spacing between the letters WITHIN EACH SPAN. this setting should not effect those letters relation to letters outside the span, or a bounding cell etc. that property would be PADDING to be set on the span (internally) or MARGIN (externally). with this simple solution, I do not see any unsolvable cases, or complex situations to need complex solutions etc. no grey area. and this fits with the behavior of many other aspects of the rendering engine, not only for text rendering, but other elements as well.
There are some serious flaws in the above proposals: Re comment 9: discontinuities are disturbing to authors. If 1 pixel of padding causes there to be less space than 0 pixels of padding, that will lead to confusion. Re comment 10: 'letter-spacing' is an inherited property. Consider: <h2 style="letter-spacing: 0.3em">The <abbr title="...">ABC</abbr>'s work</h2> Do you want there to be less space between "C" and "'" than between any other letters?
(I think the correct thing to do is put half the letter spacing on each side of each letter.)
can someone explain to me why they think that letter-spacing should have any effect on content outside of a span of letters? we're dealing with text here, and to be consistent with the current behavior of text, we should ignore anything outside of a given span WITH REGARD TO letter-spacing. padding and margin both seem perfectly adequate in addressing the leading or trailing end of such content. this "half on each side" seems moot in regards to what I'm proposing. you still shouldn't be affecting content outside the span... this behavior of affecting content outside the span is what's causing this "bug" already. adding a trailing space after the end of the span is WRONG. it's not supposed to be there. just because you're splitting that FLAW in half and having half of it on both ends doesn't make it any better and will still require frustrating work-arounds. the CSS specification itself calls letter-spacing "the space between characters" (not the space between a character and some other object) and should only affect the letters INSIDE THE SPECIFIED SPAN with no leading or trailing space. the entire problem here revolves around people insisting on this value affecting content outside the span, which as I've said many times now, seems perfectly suited to the already existing padding and margin properties. now it's completely possible I'm missing something here, or not grasping some fundamental concept... in which case I would appreciate some enlightenment. otherwise, the rest of this debate is pointless. span { letter-spacing:1em;} ab<span>cde</span>fg abc d efg ab<span style="margin:0 1em;">cde</span>fg ab c d e fg this seems to me to allow proper control over letter-spacing etc without causing any inconsistencies or ambiguous conditions etc. again, please explain to me if I am somehow missing something here.
Justin: There was so much rhetoric in your last comment (comment 13) that I couldn't actually work out what you were proposing. Could you explain the proposal on its own terms, not describing it relative to other implementations or proposals? Please take into account the point in comment 11 regarding your proposal in comment 10, which as far as I can tell is still an issue in your latest proposal. (Note that this is the most common case.) For what it's worth, I agree with dbaron; letter-spacing should IMHO be rendered as half on each side of the letter, except at the start and end of the line.
in response to #14, I think mozilla also incorrectly renders your example. I don't see how my proposal doesn't handle this situation... I'll post a URL to an image showing 2 things, and explain here what I'm describing. http://acherondesign.com/~largo/letter-spacing.png in what I proposed, considering that all the characters within the specified element are supposed to have spacing between them, this is rendered (almost) correctly... the issue here seems to lie with the <abbr> tag continuing on with the letter spacing rather than the letters themselves. this looks to me like yet another flaw with the implementation. where it seems that your (collective) proposal of spacing half on either side is closer to a better solution in regards to this specific case -as implemented-, I don't see why the <abbr> doesn't stop at either edge of the letters ABC. is there any spec that states that it has to also encompass the letter spacing as well? (I don't think I need to point out that the above example still tacks on the extra space at the end, so that in something like an inline div with a border, even with the text-align:center, there is still an "extra space" at the end.)
I'm sorry, I am having a great deal of difficulty actually understanding exactly what it is you are proposing. Could you tersely describe the algorithm? As in, describe your proposal in no more than 3 lines, without referring to any other proposals or comparing it to any implementations, and without mentioning previous comments, examples, or code snippets in this bug. Thanks!
in a specified span of characters, only apply letter-spacing between characters if there are 2 or more characters within the span. letter-spacing should be ignored on the leading and trailing end of the span even if there are other characters adjacent outside of the span. padding and/or margin can be used to set left and/or right padding/margins to the span of characters to add padding/margins in relation to other content.
another "test case" http://acherondesign.com/~largo/letter-spacing-test.png interested in comments on this.
The "Re comment 10:" part of comment 11 explains why that won't work. (Being consise is good. Otherwise nobody will read what you write.)
...although I guess you could work around that problem by putting the full letter spacing before/after any children. That might work. But it would be a good bit harder to implement, and I'm really not interested in anything that might make the code in question any more complicated, since it's far too complicated already (needlessly).
David, could you explain to me a little more clearly what you mean? I don't understand how your "re comment #10" in comment #11 explains why my proposal won't work. also, which comment are you referring to specifically? also, what exactly do you mean about the children? I'm not sure what children you're referring to. thanks. (sorry if I'm being ignorant)
Justin: regarding comment 17: Aha! Thanks. That made a lot more sense. The problem that David pointed out is with this: <span>aaa<span>bbb</span>ccc</span> According to your description, if you said: span { letter-spacing: 1em; } ...then the rendering would be: A A AB B BC C C ...which is bad, since the addition of an identically styled inline element child (the inner <span> here) should not make any visible difference to the resulting rendering.
actually, if you look at what I posted in comment #18, you'll see that I was under the impression that as the letter-spacing property is inherited, that it would still render as you say it should. the image in comment #18 explains.
Your description in comment 17 does not match that.
I believe it does. those characters are still within the span. due to it's inherited nature. perhaps I should specify a fourth line to #17 clarifying that. none the less, I thought #18 would make it clear how I thought it should behave. my apologies.
let me rephrase that... the characters adjacent to the child span are still within the parent span, and due to the inherited nature of the letter-spacing property, the spacing between B and C should still be applied, as it would still cover all the characters if not for the child span taking precedence -only between- C and D. another image to illustrate this follows: http://acherondesign.com/~largo/letter-spacing-2.png
For: span { letter-spacing: 1em; } <h1><span>T</span><span>E</span><span>S</span><span>T</span></h1> ...the rendering with your suggestion would be: TEST ...instead of: T E S T ...as it would be with the half-on-each-side idea. I think I prefer the latter rendering for that particular case.
(In reply to comment #27) I don't understand why someone would do a <span> for each letter. Having a <span> for the whole thing is generally what happens. If you really have to have one for each letter, enclose it all in a <span> -- that's what I'd expect to have to do for this behavior. The current proposal (with half on each side) makes no allowances, as far as I can tell, when the letters in question end a line. It may not be noticeable if text is left-aligned, but when right-aligned, it staggers it so that it looks like somebody put a [letter-spacing]-wide space. Already a problem, and when letter-spacing is 15px, 7px and 15px look just as ugly, especially when something nearby shows the true right margin.
My sig on a forum. This is an example of the problems caused by the current implementation and the half-spacing proposal. The spaces after "come/create/:ize" are irregular and don't belong there. Looks fine in IE6.
> The current proposal (with half on each side) makes no allowances, as far as I > can tell, when the letters in question end a line. The full proposal is "put half the letter-spacing on either side of the letter, except at the edges of the line".
(In reply to comment #30) > > The current proposal (with half on each side) makes no allowances, as far as I > > can tell, when the letters in question end a line. > > The full proposal is "put half the letter-spacing on either side of the letter, > except at the edges of the line". But wouldn't this still have the same "problem" as the other proposal with: span { letter-spacing: 1em } <span>T</span><span>E</span><span>S</span><span>T</span> rendering as TEST. And how would it handle: <span style="letter-spacing: 1em">T<span style="letter-spacing: 2em">ES</span>T</span> Would there be .5 em between T and E, or no spacing, or 1em? From what I understand it would be .5em which would be counter intuitive since the letter-spacing is only being increased.
"put half the letter-spacing on either side of the letter, except at the edges of the line". > span { letter-spacing: 1em } > <span>T</span><span>E</span><span>S</span><span>T</span> That would render as "T E S T" since each letter would have 0.5em letter spacing on either side, except at the edges. > <span style="letter-spacing: 1em">T<span style="letter-spacing: > 2em">ES</span>T</span> There would be 1.5em space between the T and the E, 2em between the E and the S, and 1.5em between the S and the final T: "T E S T". > Would there be .5 em between T and E, or no spacing, or 1em? 1.5em. Half of the T's letter-spacing from the T's right side, and half of the E's letter spacing from the E's left side.
> That would render as "T E S T" since each letter would have 0.5em letter spacing > on either side, except at the edges. Gotcha, I thought by edges you meant the edge of each span. This seems like a pretty good solution. Although I don't think this will solve the original poster's problems with kerning. After thinking about it for a while I don't think there's really any perfect way to do it which will accomodate all desired uses of letter-spacing (unless css was expanded to have stuff like letter-spacing-right, letter-spacing-left, letter-spacing-outer, letter-spacing-inner...). I still think that a proper usage of letter-spacing would be to reduce or expand the spacing between just two adjacent letters, which wouldn't be possible with the current suggestion.
another realistic test case is here: http://www.reitter-it-media.de/index_mozbug.html The W3C CSS spec clearly states that letter-spacing controls the space BETWEEN the letters, and not to the right (or left) of letters: http://www.w3.org/TR/REC-CSS1#letter-spacing
The W3C specification defines presentation, it doesn't define an algorithm.
Summary: CSS letter-spacing style extending too far → CSS letter-spacing style extends after last letter of element with letter-spacing
Assignee: layout.fonts-and-text → nobody
QA Contact: ian → layout.fonts-and-text
We should fix this by implementing the rules in http://www.w3.org/TR/css3-text/#letter-spacing . That said, it looks like there's work ongoing in bug 299943.
I just stumbled over this issue recently[1] having this as test case: data:text/html,<input maxlength="5" style="box-sizing:content-box;width:17.1ch;border:1px solid black;background-image:repeating-linear-gradient(to right, transparent, transparent 1.72ch, gray 1.72ch, gray 1.82ch);padding:0 0.4ch;font-family:monospace;font-size:6ch;letter-spacing:0.8ch;" value="0123456789"> My idea to solve this is similar to the one mentioned by Steven in comment 33. That is, introduce some syntax to allow to change the behavior. Therefore I proposed[2] to extend letter-spacing to this: letter-spacing: [ normal | <length> ] [ inside || [ outside | inline-start | inline-end ] ]? Sebastian [1] https://lists.w3.org/Archives/Public/www-style/2016Feb/0012.html [2] https://lists.w3.org/Archives/Public/www-style/2016Feb/0018.html
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: