Revising text wrapping, line breaking, and white space properties in CSS3 (CSS3 Text: 6 and 7)

Purpose
=======

The line-breaking and white space properties in CSS3 Text CR are
   - too many
   - too convoluted
to be efficient and understandable in CSS. There are a fair number of
meaningless and redundant combinations, so the discrete combinatorial
effect is not necessary. (It can actually be troublesome in a
cascading environment such as CSS.) This is a proposal for revising
these controls, mainly by simplifying them into fewer properties.

Comments, questions, additional background info, implementation notes,
and suggestions are all welcome. They should preferably be sent to
www-style@w3.org.

Notice:
Reply-to is set to www-style (which is public), so watch your follow-ups.

I will be producing the next revision of CSS3 Text, so if this topic
is important to you, you might want to pay attention. :)

Open Issues
===========

Are there any compatibility issues I'm missing?
Are all necessary combinations of white space controls available?
(MathML, i18n, I'm looking in your direction.)
For text wrapping, is there a preference for version A or version B?
Name suggestions for 'white-space-something'?

References
==========

CSS3 Text:
http://www.w3.org/TR/css3-text/#line-breaking
XSL:
http://www.w3.org/TR/xsl/slice7.html#section-N38191-Block-and-Line-related-Properties
MSWinIE:
http://msdn.microsoft.com/workshop/author/dhtml/reference/properties.asp

Part I: Breaking Lines
======================

CSS3 Text defines the following properties to affect line breaking behavior:

Property                  Origin     Controls
--------                  ------     --------
line-break                WinIE      Japanese line break rules: strict vs. loose
word-break-cjk                       Allowing breaks within CJK and/or non-CJK
word-break-inside                    Hyphenation
word-break (shorthand)    WinIE      (WinIE's name for word-break-cjk)
wrap-option               XSL:FO     Text wrapping

Line Breaking Rules
-------------------

CSS3 Text:
   line-break: normal | strict
   word-break-cjk: keep-all | normal | break-all

XSL:
   n/a

WinIE:
   line-break: normal | strict
   word-break: keep-all | normal | break-all

Proposed:
   word-break: keep-all | strict | normal | break-all

Justification:
   Practically-speaking, there's only one scale of strictness.
                   strictest <----------------------> loosest
   line-break     | irrelevant | strict | normal | normal    |
   word-break-cjk | keep-all   | normal | normal | break-all |

   * normal vs. strict line-breaking is irrelevant when keep-all takes effect.
   * The combination of strict and break-all makes little sense. (Why
     would you allow breaks in scripts like Latin, where breaking words
     in random places is wrong, but disallow breaks before small kana,
     where breaking is merely discouraged?)

Compatibility:
   wrt XSL -
     n/a
   wrt WinIE -
     The proposal uses the WinIE property name and values. It also adds
     a new value, 'strict', which will be ignored in WinIE. A style sheet
     can cause IE to recognize the same effect by also specifying
     "line-break: strict".

Hyphenation
-----------

CSS3 Text:
   word-break-inside: none | hyphenate

XSL:
   a slew of separate hyphenation controls, see spec

WinIE:
   n/a

Proposed:
   hyphenation: none | auto

Justification:

   I agree with CSS3 Text in that a simple switch is enough for CSS3.
   However, I think the name 'word-break-inside' is really obscure,
   and there's no need to create a shorthand for combining it with
   word-break. So let's just call it 'hyphenation'. This also presents
   a nicer framework for adding hyphenation limits later on.

Text Wrap
---------

CSS3 Text:
   wrap-option: wrap | no-wrap | soft-wrap | emergency

XSL:
   wrap-option: no-wrap | wrap

WinIE:
   word-wrap: normal | break-word
   [wrap / no-wrap settings given with 'white-space']

Proposed A:
   wrap-option: wrap | no-wrap | character-wrap | force-wrap
Proposed B:
   text-wrap: wrap | nowrap | character-wrap
   word-wrap: normal | break-word

Justification:
   'soft-wrap' is misleading: to most people, it means "wrap without
   inserting hard line breaks"

   'emergency' is weird and inaccurate (it wraps on regular breaks
   when it's not an "emergency"); 'force-wrap' is much more
   self-explanatory. (This value allows wrapping of very long words
   words to prevent overflow.)

Compatibility:

  * The advantage of separating out word-wrap is that it cascades
    independently. Since wrapping is traditionally set by the
    'white-space' property, which currently has no force-wrap option,
    this allows easy, current-ua-compatible retro-fitting of existing
    content: set "word-wrap: break-word" on the root element, and any
    time you set 'white-space' to allow wrapping, it will allow
    force-wrapping in UAs that support it.

  * WinIE has already implemented things this way, and we can define
    'wrap-option' as a shorthand that will be compatible with XSL.

  * If we take this route, the 'white-space' shorthand will not be able
    to set force-wrapping (because white-space and word-wrap will be
    independent).

  * If we didn't have this backwards-compat situation, it would certainly
    be better not to split them up.

Part II: White Space Handling
=============================

CSS3 Text defines the following properties to affect white space processing:

Property                  Origin     Controls
--------                  ------     --------
linefeed-treatment        XSL        how to transform line breaks
white-space-treatment     XSL        whether to preserve other white space
all-space-treatment       XSL        whether to collapse remaining white space

CSS3 Text:
   linefeed-treatment: auto | ignore | preserve | treat-as-space |
                       treat-as-zero-width-space | ignore-if-after-linefeed
   white-space-treatment: ignore | preserve | ignore-if-before-linefeed |
                       ignore-if-after-linefeed | ignore-if-surrounding-linefeed
   all-space-treatment: preserve | collapse

XSL:
   linefeed-treatment: auto | ignore | preserve | treat-as-space |
                       treat-as-zero-width-space | ignore-if-after-linefeed
   white-space-treatment: ignore | preserve | ignore-if-before-linefeed |
                       ignore-if-after-linefeed | ignore-if-surrounding-linefeed
   white-space-collapse: true | false

WinIE:
   n/a

Proposed:
   white-space-something: discard | preserve | [ collapse ||
                                                [ auto-collapse-breaks |
                                                  space-collapse-breaks |
                                                  zero-width-collapse-breaks |
                                                  discard-breaks |
                                                  preserve-breaks ] ]
   'collapse' implies 'auto-collapse-breaks'
   '*-breaks' implies 'collapse'
   examples:
     /* Discard all white space, including breaks */
      white-space-sth: discard;
     /* Preserve all white space, including breaks
        as in "white-space: pre" / "white-space: pre-wrap" */
      white-space-sth: preserve;
     /* Collapse consecutive white space into single space,
        auto-collapsing breaks and surrounding white space based on
        surrounding script context (-> space, zwsp, or discard)
        as in "white-space: normal" / "white-space: nowrap" */
      white-space-sth: collapse;
      white-space-sth: collapse auto-collapse-breaks;
      white-space-sth: auto-collapse-breaks collapse;
      white-space-sth: auto-cllapse-breaks;
     /* Collapse consecutive white space into single space,
        collapsing breaks and surrounding white space into single space */
      white-space-sth: collapse space-collapse-breaks;
      white-space-sth: space-collapse-breaks collapse;
      white-space-sth: space-collapse-breaks;
     /* Collapse consecutive white space into single space,
        collapsing breaks and surrounding white space into zero-width space */
      white-space-sth: collapse zero-width-collapse-breaks;
      white-space-sth: zero-width-collapse-breaks collapse;
      white-space-sth: zero-width-collapse-breaks;
     /* Collapse consecutive white space into single space,
        but discard collapse breaks and surrounding white space */
      white-space-sth: collapse discard-breaks;
      white-space-sth: discard-breaks collapse;
      white-space-sth: discard-breaks;
     /* Collapse consecutive white space into single space,
        but discard collapse breaks and surrounding white space
        as in "white-space: pre-lines" */
      white-space-sth: collapse preserve-breaks;
      white-space-sth: preserve-breaks collapse;
      white-space-sth: preserve-breaks;

Justification:
   The three properties in the current version of CSS3 Text, which were inherited
   from XSL, result in 60 different combinations of white-space processing rules,
   a lot of which are redundant or useless. (E.g. some result in consecutive
   zero-width spaces, some result in a combination of spaces and zwsp that has no
   useful application that I can think of, etc.)

   More importantly, these properties do not need to cascade independently, so
   they should be combined into one property that can represent all generally
   useful values.

   I believe I've covered most things. Let me know if I've missed a necessary
   value.

Part III: Shorthand
===================

CSS3 Text:
   white-space: normal | pre | nowrap | pre-wrap | pre-line

XSL:
   white-space: normal | pre | nowrap

WinIE:
   white-space: normal | pre | nowrap

Proposed A:
   white-space: normal | pre | nowrap | pre-wrap | pre-line |
                force-wrap | pre-force-wrap | line-force-wrap

Justification:
   Add values to 'white-space' shorthand to represent the force-wrap
   setting. (Only needed if we go with version A of wrap-option.)


How this fits with XSL
======================

For features that are parallel, it should be possible to map from CSS
to XSL. Going the other way, however, is not so much of a priority.
(There are several areas where CSS does not need such a fine level of
  control.)


Thanks go to Ada Chan of MS Corp. for researching and reporting on WinIE's
implementation of CSS3 Text capabilities. ~

~fantasai

Received on Monday, 4 October 2004 16:06:49 UTC