What to do about the 'ch' length unit? (Mozilla vendor specific)

NEW
Unassigned

Status

()

Core
CSS Parsing and Computation
12 years ago
4 years ago

People

(Reporter: mats, Unassigned)

Tracking

(Blocks: 1 bug, {css-moz})

Trunk
css-moz
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

12 years ago
What to do about the 'ch' length unit? (Mozilla vendor specific)

(Followup from bug 281972)

The only real internal dependence is:
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/content/html/content/src/nsHTMLPreElement.cpp&rev=1.63&root=/cvsroot&mark=127,145,146#125

That is, to wrap a <pre> exactly at the number of characters specified by
WIDTH (or COLS) we need a unit that is based on the width of a character
in the current font.

The problem is that all the relative widths that are font based are
relative the height, not the width:
http://www.w3.org/TR/CSS21/syndata.html#length-units
http://www.w3.org/TR/2001/WD-css3-values-20010713/#lengths

So, to get rid of this Mozilla vendor unit I see two options.
1. convince the CSS working group that 'ch' is needed
2. remove it and introduce a "nsPreFrame" that looks at the
   WIDTH/COLS attr to set its width during reflow (similar to what
   nsTextControlFrame does).
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/forms/nsTextControlFrame.cpp&rev=3.191&root=/cvsroot&mark=1583,1606,1607#1582

http://lxr.mozilla.org/mozilla/search?string=eStyleUnit_Chars
http://lxr.mozilla.org/mozilla/search?string=eCSSUnit_Char
http://lxr.mozilla.org/mozilla/search?string=eCSSKeyword_ch

Comment 1

12 years ago
It has been proposed:
 <http://lists.w3.org/Archives/Public/www-style/1999Dec/0026.html>

(I could not find any other emails about it.)

Updated

12 years ago
Keywords: css-moz
(Reporter)

Comment 2

12 years ago
I suppose this is an alternative as well:
3. drop the 'ch' keyword and only use eCSSUnit_Char internally
Or (a variant of (3)) we could rename it to -moz-ch to allow round-tripping.

That said, it's needed to allow the cascade to work correctly, and we should
probably be using it for input and textarea as well for exactly that reason.
(Reporter)

Comment 4

12 years ago
I agree with the cascade argument, but input and textarea is using
nsIFontMetrics::GetAveCharWidth() rather than the width of a 'M',
so it's not the same measure. Hm, -moz-avg-ch perhaps? 
(Reporter)

Comment 5

12 years ago
Given that 'ch' is only intended for use with fixed width fonts at the moment,
I suppose we could change this:
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/generic/nsHTMLReflowState.cpp&rev=1.218&root=/cvsroot&mark=2277,2294-2306#2276

to use nsIFontMetrics::GetAveCharWidth() instead.
I think it's reasonable to expect it to be equal to the width of a 'M' in a
fixed width font, yes?

If so, we can use it for input and textarea too.

Also, I would like length units to be universal, at the moment 'ch' can't
be used to specify 'height' for example (it results in zero height).
So there are two issues here:

1)  Should we have an internal "ch" unit that we use for <pre> and <input>?  I
think the answer is yes.

2)  Should this be accessible from CSS stylesheets (that is, parsed)?  I think
the answer here should be "not unless it's a -moz unit".

For the rest, having this work for all lenths could be interesting -- the "ch"
unit depends on the font metrics, which depend on the lang group, which comes
from the "visibility" struct.  But we have lengths in the "display" struct,
which makes "display" depend on "visibility".  I don't think that's desirable
(and I'm not sure it doesn't introduce a circular dependency).  Also, should
"ch" do all the weirdness that nsTextControlFrame does right now for
non-fixed-width fonts?  I suspect it should...

Comment 7

12 years ago
If there is a "ch" unit, what will be the impact to characters that is wider
than "M", especially double-byte characters. Consider this:
<pre style="width: 10ch">
1234567890
&#19968;&#20108;&#19977;&#22235;&#20116;&#20845;&#19971;&#20843;&#20061;&#21313;
</pre>

Should Mozilla wraps the second line at "&#20116;" or "&#20845;" (around the tenth charcter
on the first line), or "&#21313;" (exactly the tenth character)?

If it is the former case, maybe it should be name "byte" so as to reflect the
fact that it is not counting character-width but byte-width.
> If there is a "ch" unit, what will be the impact to characters that is wider
> than "M"

That's up to the GetAveCharWidth implementation in the relevant nsIFontMetrics.
 You can test it using <input size="10">, since that already uses the function.
 And yes, this should be counting characters, not bytes.

The algorithm used by text inputs handles both fixed-width and proportional
fonts.  Perhaps something like that algorithm would provide a reasonable
definition for 'ch' for all cases?

http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/forms/nsTextControlFrame.cpp&rev=3.191&mark=1602-1644#1582
(In reply to comment #6)
> For the rest, having this work for all lenths could be interesting -- the "ch"
> unit depends on the font metrics, which depend on the lang group, which comes
> from the "visibility" struct.  But we have lengths in the "display" struct,
> which makes "display" depend on "visibility".  I don't think that's desirable
> (and I'm not sure it doesn't introduce a circular dependency).

Yeah, this is a problem.  I've said a few times that the CSS WG should have a
dependency map for computed value calculation.  We probably need to do the same,
and make sure that we don't get dependencies across structs.
Blocks: 281630

Comment 11

12 years ago
The rationale for bug 281630 which this bug has been marked as blocking is that
although the default Windows and Linux UI fonts are reasonably similar so that
dialogs designed on one work on the other their aspect ratio and that of the
default Mac UI font differ sufficiently for us to have had to put various hacks
into e.g. the preferences and account manager windows to size them appropriately
which a native "ch" (or whatever) unit would have accomplished automatically.

Of course the bug also affects people who change their UI font to something
sufficiently dissimilar but they've currently just had to live with it.
(Reporter)

Updated

11 years ago
Depends on: 363573
(Reporter)

Comment 12

11 years ago
"CSS3 Values and Units" now includes a 'ch' unit:
http://www.w3.org/TR/css3-values/#relative0

Should we morph this bug into a meta bug with dependencies to the bugs that
handles the specific errors?
(Reporter)

Updated

11 years ago
Depends on: 363706
css3-values says:

  The width of the "0" (ZERO, U+0030) glyph found in the font for the font size used to render. If the "0" glyph is not found in the font, the average character width may be used.

AddCoord in nsFrame.cpp and GetAbsoluteCoord in nsLayoutUtils.cpp use the width of the "M".

nsTextControlFrame::CalcIntrinsicSize does something more complicated, "for compatibility with IE".

(If my memory is correct, the wording in css3-values is there because it's what the IE folks said IE does.  So it might be even more compatible with IE.)
Oh, and nsTextControlFrame::CalcIntrinsicSize also accounts for letter-spacing, which is harder on a unit...
Depends on: 371043
Assignee: dbaron → nobody
QA Contact: ian → style-system
See patches just added to bug 363706 - we could make CalcIntrinsicSize use GetZeroOrAveCharWidth() instead and possibly take out some of the "for IE compatibility" complications.

Comment 16

8 years ago
Isn't this fixed with bug 363706?
Not really, no.

Updated

5 years ago
Blocks: 741643
You need to log in before you can comment on or make changes to this bug.