Re: Text selector [was Re: breaking overflow]

On Jan 6, 2010, at 8:39 AM, Tab Atkins Jr. wrote:

> On Tue, Jan 5, 2010 at 5:40 PM, Brad Kemper <brad.kemper@gmail.com> wrote:
>>> or
>>> p::text('ABCD') { color:red; }
>>> p::text('CDEF') { color:blue; }
>>> <p>ABCDEF</p>
>> 
>> Tab and I resolved this to our own general satisfacion, I thought, in the
>> earlier part of the thread. "AB" would be red and "CDEF" would be blue.
> 
> No, after further thought this isn't resolved properly.  What's the
> behavior if both ::text() selectors applied display:block; to the
> content?  Colors override each other nicely; display changes do not.
> You'd end up with precisely the problem I was decrying earlier about
> allowing it to match across element boundaries - it would display as:
> 
> AB
> CD
> EF
> 
> This would be very confusing to authors.

I don't think it is any more confusing than most other CSS specs, where a clear understanding of the spec helps one understand what happens with edge cases.

Or, if technically feasible, we could just further refine our definition, so that properties that are identical between two adjacent ::text() pseudo-elements (the first two of the three you created, for example) are treated as though they belonged to the same element for the purposes of that property. Then, in your example you'd get the (perhaps) more intuitive version of this:

AB
CDEF

>>> I think a good way to address your use case would be to extend the "content"
>>> property as applied to elements, so we can replace the contents of an
>>> element with children with different styles. Right now CSS3 supports, for
>>> example,
>>> h1 { content: url(welcome.png) " to my " url(page.png); font:...; }
>>> With creative use of :before and :after you can have
>>> h1:before { content: "Welcome"; font:...; }
>>> h1 { content: " to my "; font:...; }
>>> h1:after { content: "Page"; font:...; }
>>> We could extend this to support an unlimited number of different child
>>> pseudo-elements.
>> 
>> As I said, that is but a single use case out of many.
> 
> That addresses my main use-case, though.  It would be kinda weird, but
> it would work.  

Yes, a lot weirder than just being able to select based on text.

>>>> Here was something I showed earlier:
>>>> 
>>>> ::text("Example \d: *\n") {
>>>> display: block;
>>>> padding: .5em;
>>>> margin: 1 em 0;
>>>> border: 1px solid #999;
>>>> background-color: #eee;
>>>> }
> 
> This probably should be marked up semantically. 

"Probably should" doesn't mean "is". CSS is not here to police markup, it is here to style markup The markup is not always what we want it to be, and the markup we'd want for an idealized perfectly semantic Web is not always even available to markup authors. But something that is almost always part of the markup is text. I see no reason to exclude raw text as a candidate for styling on purely philosophical grounds. The text is part of the marked up document.

As the "Web Style Sheets" page[1] states, "By attaching style sheets to structured documents on the Web (e.g. HTML), authors and readers can influence the presentation of documents without sacrificing device-independence **or adding new HTML tags**."


>>>> Here is a way to highlight the company name whenever it appears in a
>>>> paragraph or list item:
>>>> 
>>>> p::text("ACME"), li::text("ACME") { background-color: yellow; }
> 
> This is more borderline.  It's possible that it should just be done up
> with <b> each time.

Aside from the debate about how semantic "<b>" is, that is not a reasonable expectation. A site can be very well marked up according to best practices, and not have its company name in bold or any other tag. 

Or how about if I want to create a user style sheet that highlights my name whenever it appear on any page? That's a perfectly reasonable (albeit egotistical, arguably) styling desire. But it is not reasonable for me to ask every site author on the Web that might mention my name to also put it in bold.

>>>> Here is a way to use a mono-spaced font for numbers:
>>>> 
>>>> p::text("\d+") { font-family: "Courier New", Courier, monospace; }
> 
> This one is indeed a pure styling issue.  It could perhaps be
> addressed another way, though, by having something targetting
> number-styling directly, either as a specialized selector or as a
> number-style property or similar. 

So every time I want to arbitrarily style something that doesn't already have a tag in HTML, I need to try to convince the HTML working group to implement a new type of tag that somehow matches some meaningful semantics for my choice, and then wait and hope they do it? Or else, hope I have some control over the markup, and insert a completely non-semantic SPAN, as we all do now? With ::text() we have an opportunity to go far beyond that limitation, to much more powerfully style the pages that are given to us (which, in the case of user style sheets are all the pages of the entire Web). 

This doesn't mean we abandon meaningful markup. That will alway be an easier way to select and style things meaningfully, and (assuming it has important non-styling value as well) can stand on its own two feet as a reasonable goal of authors and HTML spec writers.

>>>> Here is a way to turn a greater-than glyph into a picture of a hand
>>>> pointing right:
>>>> 
>>>> ::text(">") {
>>>>   height:20px; width:40px;
>>>>   background-image:url(right-pointing-hand.png);
>>>>   display:inline-block;
>>>>   color: transparent;
>>>> }
> 
> Why aren't you using the picture for your breadcrumb separators
> anyway?  As well, why are breadcrumb separator in the content anyway?
> I do my breadcrumbs as an <ol>, with the <li>s made inline, the list
> markers removed, and breadcrumb markers inserted with ::before.  The
> markers aren't content in the first place.

They are if they are in the markup I'm styling. This proposal isn't an argument about how to best mark things up. If that example really bothers you, then pick another one. Suppose I want to replace every copyright symbol with a exactly sized raster image that my legal department insists on, but still have to have the regular one for people with style sheets off or whatever. Or maybe I want to replace all my periods at the end of sentences with little peace signs or hearts. It may be silly styling, but as a CSS author, I should not have to seek approval from a WG in order to do it. The WG should imbue me with the power to to style the markup I am using, whether they like the markup choices I made or not, if it is technically feasible to do so.

>>>> Here is a way to quickly strike out your old phone number throughout the
>>>> site, until you've had a chance to update it, or in case you suspect that it
>>>> is still on some of the hundreds of pages you don't control but provide CSS
>>>> files for:
>>>> 
>>>> ::text("\(555\) 555-5555") { text-decoration: line-through; }
> 
> This is best accomplished with a search-and-replace across your
> website.  If you don't have access to some pages, you have a problem
> that needs to be solved *there*, rather than being hacked around with
> a CSS backdoor.  

It's not hacked. I know I will need to search and replace, and work with my vendors, etc. But just as I might sometimes want to display a "this site is temporarily down" message, or "the page you are looking for is no longer available" message, I might want to use styling as a quick and temporary way to indicate that there is a problem with this bit of info is not valid.

> Now that it's been pointed out that my main use-case for ::text
> (fancy, non-semantic styling of page headers) can be addressed equally
> well by using generated content, and without any of the inherent
> ambiguities of a full-powered ::text,

Ambiguities can be resolved. The kludginess of that solution is worse, IMO. 

> I'm seeing a lot less use for
> it.  

I made the proposal not just to solve that one problem on your one site, but to be a powerful aid to styling. I just made up these examples on short notice, but I am frequently wishing for it in my work, and truly believe it would be very, very useful in a very broad way. Saying it's not useful is like saying that styling a SPAN is not useful, so we shouldn't allow CSS to affect SPAN elements.

> Using it as a pure-inline element with restrictions similar to
> ::first-line might still be cool, but I'm much less convinced of its
> usefulness now.  (Though, a lot of the badness of ::first-line doesn't
> apply here, since this is content-based, not structure-based; you
> can't apply styling via it that changes what it matches, like you can
> with first-line and, say, font-size.)
> 
> ~TJ

Received on Wednesday, 6 January 2010 18:43:36 UTC