Posts in the CSS Category

CSS3 Feedback: Layout

Published 15 years, 10 months past

(This is part of the Feedback on ‘WaSP Community CSS3 Feedback 2008’ series.)

In this round, layout.  Not all of it, but the bits that struck me as either really useful or really, really way too long overdue.

Float containment yes, we need a property that does just that.  As long as we’re tied to floats for layout—and I plan to rant about that soon—there should be a clear, unambiguous, intentionally defined property that tells elements to wrap themselves around floated descendant elements.  overflow works in most cases but can fall down in unusual circumstances (I’ve seen scrollbars appear where none were actually needed) and anyway, it wasn’t intended to provide the wrapping effect in the first place.  That it does so is a happy side effect, but it’s still a side effect.  The rest of the float-wrapping techniques are even more convoluted.  “There are already ways to do that so we don’t need a property” is rather like saying “we can already do layout with tables so why do we need CSS layout?”.

Positioning by center yes, please.  The way to center an absolutely positioned element within its containing block is to set the top and left to 50% each and then define negative top and left margins that are half the positioned element’s height and width.  That’s just awful, and requires at least an explicit width, if not an explicit height.  When I did the structured timeline, here’s how I got the version numbers to center below the dots:

#timeline tbody td p {
	position: absolute;
	top: 50%;
	width: 2.1em;
	margin: -5px 0 0 -1em;
}

See that -1em left margin, and the 2.1em width?  Just to get the center of positioned elements’ boxes sit on top of a certain left offset (defined elsewhere in the CSS).  Ditto the negative top margin, to pull it upward just enough so that the elements’ boxes would have the point five pixels down from their tops line up with the vertical midpoint of their containing blocks.

I wanted to do something like this:

#timeline tbody td p {
	position: absolute;
	top: 50%;
	position-anchor: 50% 5px;
}

That would have said that the point in the center of the absolutely positioned element should be placed at the point in the containing block 21.7% down from the top and 44% of the way across from the left.  That would hang the positioned element’s center on that point, regardless of the size of the positioned element—note that I took out the width.  I could stop defining explicit sizes and just let the elements be the size they want to be to show their content.

The problem is that approach doesn’t fit at all well with the way positioning layout is defined.  Suppose I said this:

#timeline tbody td p {
	position: absolute;
	top: 50%; bottom: 0;
	left: 50%; right: 25%;
	position-anchor: 50% 5px;
}

Now what?  I’m not even sure myself.  Maybe define rename it to position-offset and define percentages to be relative to the height and width of the positioned element (not its containing block), so that it doesn’t interact directly with the offset properties like top and right?

All I want is a way to hang elements off of offset points, and not be restricted to the corners of the elements, and have the solution work even when the elements have automatic height and width, and not require extra markup to make it happen.  Oh, and a ponycar.

Box sizing what in the nine hells of Valeria is taking so long?  We needed that one ten years ago.  I no longer care if it’s done as its own property or as new keywords on height and width.  I just want it.  Someone will make it happen, with or without the WG or implementors—mark my words.

Same-height elements yes, a way to tie element heights (whether they’re siblings or not) together would be welcome, although I can see how specifying it in an implementable would be tricky; no, display: table-cell  is not the answer.  Soon I will rant about this.  Soon.


CSS3 Feedback: Selector Blocks

Published 15 years, 10 months past

(This is part of the Feedback on ‘WaSP Community CSS3 Feedback 2008’ series.)

Out of all the selector feedback, selector blocks was the part that really caught my attention.  I also see the usefulness of a parent selector, but that one has come up many times before, and it’s always died at the doorstep of implementors, who point out that it’s far too difficult to implement without serious performance penalties and even risk of browser lockup.  See, for example, the comment left by David Hyatt on Shaun Inman’s post on the idea.  Similarly, I think constants (or macros or whatever they’re called) are a great idea and would be very helpful, especially if you’re coding up a Jason Special.  Both are loaded with use cases, so I don’t feel like I can add a lot; besides, constants are already in the WG charter, so there’s once more hope in the land.

So anyway, selector blocks.  To pick one recent example, while working on a project that should very soon see the light of day, I had a situation involving the following chunk of rules.

h1, h2, h3, h4, h5, h6, table {
   font: 1em Arial, "Helvetica Neue", Helvetica, sans-serif;}
h1 {font-size: 275%;}
h3:first-child {margin-top: 1em;}
p.tagline {margin: -0.25em 0 1.25em;
   font-size: 125%;
   color: #7B7960;}
h3 {margin: 1.5em 0 0.25em; font-size: 125%;}
h3:before {font-size: 75%; counter-increment: subhead;}
h4 {margin: 2.5em 0 0.75em;
   text-transform: uppercase; font-size: 125%;
   color: #928F59;}
p {margin: 0 0 1em;}
ul {padding-left: 1.5em;}
ul li {list-style: disc; margin: 0.5em 0;}

Nothing unusual about them, of course, unless you count my use of counters.  These rules had been written early on in development, and the design had evolved around that part of the document.  As more page components were added, I realized that I needed to scope all these rules to one section of the document: specifically, a div with a class of main.  So here’s what I had to do.

.main h1, .main h2, .main h3, .main h4, 
.main h5, .main h6, .main table {
   font: 1em Arial, "Helvetica Neue", Helvetica, sans-serif;}
.main h1 {font-size: 275%;}
.main h3:first-child {margin-top: 1em;}
.main p.tagline {margin: -0.25em 0 1.25em;
   font-size: 125%;
   color: #7B7960;}
.main h3 {margin: 1.5em 0 0.25em; font-size: 125%;}
.main h3:before {font-size: 75%; counter-increment: subhead;}
.main h4 {margin: 2.5em 0 0.75em;
   text-transform: uppercase; font-size: 125%;
   color: #928F59;}
.main p {margin: 0 0 1em;}
.main ul {padding-left: 1.5em;}
.main ul li {list-style: disc; margin: 0.5em 0;}

This, on the other hand, is what I really wanted to do:

.main {
   h1, h2, h3, h4, h5, h6, table {
      font: 1em Arial, "Helvetica Neue", Helvetica, sans-serif;}
   h1 {font-size: 275%;}
   h3:first-child {margin-top: 1em;}
   p.tagline {margin: -0.25em 0 1.25em;
      font-size: 125%;
      color: #7B7960;}
   h3 {margin: 1.5em 0 0.25em; font-size: 125%;}
   h3:before {font-size: 75%; counter-increment: subhead;}
   h4 {margin: 2.5em 0 0.75em;
      text-transform: uppercase; font-size: 125%;
      color: #928F59;}
   p {margin: 1em 0;}
   ul {padding-left: 1.5em;}
   ul li {list-style: disc; margin: 0.5em 0;}
}

Or, if necessary, to put the whole original chunk into its own style sheet and then do one of the following:

div.main {@import url(main-style.css);}

<div class="main" style="@import url(main-style.css);">

Interestingly, the latter is theoretically possible, thanks to the more advanced profiles in the CSS module “Syntax of CSS rules in HTML’s ‘style’ attribute“.  I’m not aware of the former having been seriously considered (despite my best efforts, once upon a time), though it’s always possible I missed something.

But either one of those approaches would be a last resort, in my opinion.  I’d much rather just wrap the whole chunk in .main { }, like I showed previously, and be done with it.  That capability would also simplify certain annoyingly repetitive patterns, like the very first of those rules.  I think it’s pretty obvious which of the following is easier to write and maintain:

body.home #content .entry h2, 
body.home #content .entry h3, 
body.home #content .entry h4, 
body.home #content .entry h5, 
body.home #content .entry h6 {...}

body.home #content .entry {
   h2, h3, h4, h5, h6 {...}
}

I mean, just look at the former, and imagine what one goes through to write it in the first place.  Copy, paste, paste, paste, paste, paste… maddening.  And that’s just for a small block of CSS like this one.  Imagine the tedium of doing this for a block of 50 rules, or 150.  (Also, this is the the same thing that was requested in the feedback as “Grouped Alternates“, albeit with a different syntax.)

One objection to this sort of pattern is that it increases dependence on descendant selectors, which are computationally inefficient.  But it doesn’t: I had to create a whole bunch of descendant selectors as it was, and did so far more clumsily.  And had I missed a command-V somewhere, I’d have had styles that applied outside their intended subtree.  Introducing a way to nest blocks like this doesn’t change anything except make it easier and more maintainable to do what we already do.  Honestly, it’s pretty much impossible to increase dependence on descendant selectors.  The best we can do now is make them less difficult to write.

I realize that the syntax I depict would cause backwards-compatibility problems, as in older browsers would not behave as intended when exposed to this sort of thing, but I’ve also stopped being concerned about that.  We can’t keep holding ourselves hostage to decisions made a decade or more back.  Provide the capability and authors will use it when they can.  Over time, its use will become more prevalent—kind of the same way authors adopted CSS in the first place.

I also realize that this case has been made time and again by many, many other people.  This isn’t even the first time I’ve made this case, though I think the other times were within the WG and therefore off the public record.  The fact that it keeps being made is a strong indicator that the need exists, and dismissing the idea because the same end effect can be achieved with existing selector syntax (as shown above) isn’t acceptable.  That’s like saying that complex selection effects can be achieved with JavaScript or XPath, so there’s no need for advanced CSS selectors.

So that’s my use case.  I actually have a bunch more, but they all follow the same basic pattern: the desire to group rules together into subsections of a document, or to otherwise simplify the writing of CSS.


Feedback on ‘WaSP Community CSS3 Feedback 2008’

Published 15 years, 10 months past

Back before holiday season hit, Elika Etemad—better known as Fantasai—published WaSP Community CSS3 Feedback 2008.  I gave it a read and came away with a number of things I wanted to say.  So many things, in fact, that I’ll need to split them up into a series of posts.  This here post will serve as introduction and hub, with links to the follow-on entries added as they’re published.  All very Bray-ny, no?  (Go ahead, groan.  It only encourages me.)

Here you go:

  1. Selector blocks
  2. Layout
  3. Wanted: Layout System
  4. Animated Shapes
  5. Graphical Thoughts

I want to make clear up front that I’m not going to address every single point in the feedback document: it’s just too incredibly huge.  I did think about making my own copy and then just filling in my reactions to each point, but that didn’t scale very well.  Not only did it seem really overbearing and maybe just a touch egotistical, but some of my reactions were based on related topics in separate areas of the original.  Besides, I know what it’s like trying to read a really, really long article, so breaking it up and just focusing on the parts that got me fired up made way more sense.

There is one thing I want to address before I start serving up the follow-on installments.  At the end of Fantasai’s post, there’s a link to my 2006 post about the benefit of having a community liaison, someone who bridges the gap between the WG and the public.  She then asks if anyone is interested in volunteering, but personally, I don’t see the need.  The WG already has a community liaison:  it’s you, Fantasai.  It has been for some time now, thanks to your regular and informative CSS WG blog posts and other outreach work such as “WaSP Community CSS3 Feedback 2008”.  The job is being done, and being done very well, I don’t think there’s any doubt that the Working Group is much, much better for it.


London CSS/XHTML Workshop

Published 15 years, 10 months past

Hey all, and especially those of you in the EU: I’m going to be doing an all-new one-day workshop in London in early March via the offices of Carson Workshops, for whom I’ve done workshops in the past.  Previously I’ve done two-day gigs with a beginner-to-intermediate skill range, but this time we’re trying something different.  I’m going to get down and dirty with some tough topics, and really push hard at the limits of what CSS and semantic markup can do.

You can get the details at the CW site, and note the special price for the first quarter of the seats.  That’s right, this will be a small, intimate workshop, with plenty of chances for questions about and challenges to what I’m saying.  Previous workshops have featured some really great conversations among everyone there, and I expect the same this time around.

I had meant to blog this before life intervened and took me out of my wifi cloud (and more on that soon), so time is a little more of the essence than usual—if you know someone who you think might be interested, pass the word on, willya?  Thanks!


Using HTTP Headers to Serve Styles

Published 15 years, 11 months past

How many times have you played out the following scenario?

  1. Makes local changes to your style sheet(s).
  2. Upload the changes to the staging server.
  3. Switch to your browser and hit “reload”.
  4. Nothing happens.
  5. Force-reload. Nothing happens.
  6. Go back to make sure the upload is finished and successful.
  7. Reload again.  Still nothing.
  8. Try sprinkling in !important.  Upload, reload, nothing.
  9. Start swearing at your computer.
  10. Check Firebug to see what’s overriding your new styles.  Discover they aren’t being applied at all.
  11. Continue in that vein for several minutes before realizing you were hitting reload while looking at the live production server, not the staging server.
  12. Go to the staging server and see all your changes.
  13. Start swearing at your own idiocy.

This happened to me all the time as we neared completion of the redesign of An Event Apart.  It got to the point that I would deliberately add obvious, easily-fixable-later errors to the staging server’s styles, like a light red page background.

Now that we’re launched and I have time to actually, you know, think about how I do this stuff, it occurred to me that what I should have done is create a distinct “staging” style sheet with the obvious error or other visual cue.  Maybe repeat the word “staging” along the right side of the page with a background image, like a watermark:

html {background: url(staging-bg.png) 100% 50% repeat-y;}

Okay, cool.  Then I just need to have that served up with every page on the staging server, without it showing up on the production server.

One way to do that is just make sure the image file never migrates to production.  That way, even if I accidentally let the above CSS get onto production, the user will never see it.  But that’s inelegant and wasteful, and fragile to boot: if the styles accidentally migrate, who’s to say the image won’t as well?  And while I’m sure there are all kinds of CMS and CVS and Git and what-have-you tricks to make sure that doesn’t happen, I am both clumsy and lazy.  Not only do I have great faith in my ability to screw up my use of such mechanisms, I don’t really want to be bothered to learn them in the first place.

So: why not send the link to the style sheet using HTTP headers?  Yeah, that’s the ticket!  I can just add a line to my .htaccess file on the staging server and be done.  Under Apache, which is what I use:

Header add Link "</staging.css>;rel=stylesheet;type=text/css;media=all"

Those angle brackets are, so far as I can tell, absolutely mandatory, so bear that in mind.  And of course the path in those brackets can be absolute, unlike what I’ve shown here.  I’m sure there are simple PHP equivalents, which I’ll leave to others to work out.  I really didn’t need to add the media=all part, but what the heck.

Seems so simple, doesn’t it?  Almost… too simple.  Like there has to be a catch somewhere.  Well, there is.  The catch is that this is not supported by all user agents.  Internet Explorer, for one; Safari, for another.  It does work in Opera and Gecko browsers.  So you can’t deploy this on your production server, unless of course you want to use it as a way to hide CSS from both IE and Safari.  (For whatever reason.)  It works great in Gecko-based production environments like mine, though.

I looked around for a quick how-to on do this, and couldn’t find one.  Instead, I found Anne van Kesteren’s test page, whose headers I sniffed in order to work out the proper value syntax; and a brief page on the Link header that didn’t mention CSS at all.  Nothing seemed to put the two of them together.  Nothing until now, that is.


JavaScript Will Save Us All

Published 16 years, 2 months past

A while back, I woke up one morning thinking, John Resig’s got some great CSS3 support in jQuery but it’s all forced into JS statements.  I should ask him if he could set things up like Dean EdwardsIE7 script so that the JS scans the author’s CSS, finds the advanced selectors, does any necessary backend juggling, and makes CSS3 selector support Transparently Just Work.  And then he could put that back into jQuery.

And then, after breakfast, I fired up my feed reader and saw Simon Willison‘s link to John Resig’s nascent Sizzle project.

I swear to Ged this is how it happened.

Personally, I can’t wait for Sizzle to be finished, because I’m absolutely going to use it and recommend its use far and wide.  As far as I’m concerned, though, it’s a first step into a larger world.

Think about it: most of the browser development work these days seems to be going into JavaScript performance.  Those engines are being overhauled and souped up and tuned and re-tuned to the point that performance is improving by orders of magnitude.  Scanning the DOM tree and doing things to it, which used to be slow and difficult, is becoming lightning-fast and easy.

So why not write JS to implement multiple background-image support in all browsers?  All that’s needed is to scan the CSS, find instances of multiple-image backgrounds, and then dynamically add divs, one per extra background image, to get the intended effect.

Just like that, you’ve used the browser’s JS to extend its CSS support.  This approach advances standards support in browsers from the ground up, instead of waiting for the browser teams to do it for us.

I suspect that not quite everything in CSS3 will be amenable to this approach, but you might be surprised.  Seems to me that you could do background sizing with some div-and-positioning tricks, and text-shadow could be supportable using a sIFR-like technique, though line breaks would be a bear to handle.  RGBa and HSLa colors could be simulated with creative element reworking and opacity, and HSL itself could be (mostly?) supported in IE with HSL-to-RGB calculations.  And so on.

There are two primary benefits here.  The first is obvious: we can stop waiting around for browser makers to give us what we want, thanks to their efforts on JS engines, and start using the advanced CSS we’ve been hearing about for years.  The second is that the process of finding out which parts of the spec work in the real world, and which fall down, will be greatly accelerated.  If it turns out nobody uses (say) background-clip, even given its availability via a CSS/JS library, then that’s worth knowing.

What I wonder is whether the W3C could be convinced that two JavaScript libraries supporting a given CSS module would constitute “interoperable implementations”, and thus allow the specification to move forward on the process track.  Or heck, what about considering a single library getting consistent support in two or more browsers as interoperable?  There’s a chance here to jump-start the entire process, front to back.

It is true that browsers without JavaScript will not get the advanced CSS effects, but older browsers don’t get our current CSS, and we use it anyway.  (Still older browsers don’t understand any CSS at all.)  It’s the same problem we’ve always faced, and everyone will face it differently.

We don’t have to restrict this to CSS, either.  As I showed with my href-anywhere demo, it’s possible to extend markup using JS.  (No, not without breaking validation: you’d need a custom DTD for that.  Hmmm.)  So it would be possible to use JS to, say, add audio and video support to currently-available browsers, and even older browsers.  All you’d have to do is convert the HTML5 element into HTML4 elements, dynamically writing out the needed attributes and so forth.  It might not be a perfect 1:1 translation, but it would likely be serviceable—and would tear down some of the highest barriers to adoption.

There’s more to consider, as well: the ability to create our very own “standards”.  Maybe you’ve always wanted a text-shake property, which jiggles the letters up and down randomly to look like the element got shaken up a bit.  Call it -myCSS-text-shake or something else with a proper “vendor” prefix—we’re all vendors now, baby!—and go to town.  Who knows?  If a property or markup element or attribute suddenly takes off like wildfire, it might well make it into a specification.  After all, the HTML 5 Working Group is now explicitly set up to prefer things which are implemented over things that are not.  Perhaps the CSS Working Group would move in a similar direction, given a world where we were all experimenting with our own ideas and seeing the best ideas gain widespread adoption.

In the end, as I said in Chicago last week, the triumph of standards (specifically, the DOM standard) will permit us to push standards support forward now, and save some standards that are currently dying on the vine.  All we have to do now is start pushing.  Sizzle is a start.  Who will take the next step, and the step after that?


Caught In The Camera Eye

Published 16 years, 6 months past

Just when you thought the whole embedded-video thing couldn’t get any worse, here I come with videos featuring, well, me.

The most recent is a short clip from one of my presentations at An Event Apart back in April, debug / reboot, where I comment at my usual pace on the suppression of quotation marks in my reset styles and why I think relying on browser-generated quotation marks is a bad idea.  You also get to see my hair before it got to be the length it is now, which is even longer.  There’s a complete transcription on that page, by the way, courtesy Mr. Z.

Then there’s the vaguely silly one, in which I attempt to debug my clothing while sitting in my living room.  The main takeaway here, I think, is that my speech patterns on stage are just about the same as those in “regular life”.  Pity my family.

So there’s me in the movies.  It’s nowhere near as epic-ly mëtäl as some other folks’ videos, but I suppose we all do what we can.


Characteristic Confusion

Published 16 years, 7 months past

In the course of building my line-height: normal test page, I settled on defaulting to an unusual but still pervasive font family: Webdings.  The idea was that if you picked a font family in the dropdown and you didn’t have it installed, you’d fall back to Webdings and it would be really obvious that it had happened.

(A screenshot of the symbols expected from Webdings: an ear, a circle with a line through the middle, and a spider.)

Except in Firefox 3b5, there were no dings, web or otherwise.  Instead, some serif-family font (probably my default serif, Times) was being used to display the text “Oy!”.

It’s a beta, I thought with a mental shrug, and moved on.  When I made mention of it in my post on the subject, I did so mainly so I didn’t get sixteen people commenting “No Webdings in Firefox 3 betas!” when I already knew that.

So I didn’t get any of those comments.  Instead, Smokey Ardisson posted that what Firefox 3 was doing with my text was correct.  Even though the declared fallback font was Webdings, I shouldn’t expect to see it being used, because Firefox was doing the proper Unicode thing and finding me a font that had the character glyphs I’d requested.

Wow.  Ignoring a font-family declaration is kosher?  Really?

Well, yes.  It’s been happening ever since the CSS font rules were first implemented.  In fact, it’s the basis of the whole list-of-alternatives syntax for font-family.  You might’ve thought that CSS says browsers should look to see if a requested family is available and then if not look at the next one on the list, and then goes to render text.  And it does, but it says they should do that on a per-character basis.

That is, if you ask for a character and the primary font face doesn’t have it, the browser goes to the next family in your list looking for a substitute.  It keeps doing that until it finds the character you wanted, either in your list of preferred families or else in the browser’s default fonts.  And if the browser just can’t find the needed symbol anywhere at all, you get an empty box or a question mark or some other symbol that means “FAIL” in font-rendering terms.

A commonly-cited case for this is specifying a CJKV character in a page and then trying to display it on a computer that doesn’t have non-Romance language fonts installed.  The same would hold true for any page with any characters that the installed fonts can’t support.  But think about it: if you browse to a page written in, say, Arabic, and your user style sheet says that all elements’ text should be rendered in New Century Schoolbook, what will happen?  If you have fonts that support Arabic text, you’re going to see Arabic, not New Century Schoolbook.  If you don’t, then you’re going to see a whole lot of “I can’t render that” symbols.  (Though I don’t know what font those symbols will be in.  Maybe New Century Schoolbook?  Man, I miss that font.)

So: when I built my test, I typed “Oy!” for the example text, and then wrote styles to use Webdings to display that text.  Here’s how I represented that, mentally: the same as if I’d opened up a text editor like, oh, MS Word 5.1a; typed “Oy!”; selected that text; and then dropped down the “Font” menu and picked “Webdings”.

But here’s how Firefox 3 dealt with it: I asked for the character glpyhs “O”, “y”, and “!”; I asked for a specific font family to display that text; the requested font family doesn’t contain those glyphs or anything like them; the CSS font substitution rules kicked in and the browser picked those glyphs out of the best alternative.  (In this case, the browser’s default fonts.)

In other words, Firefox 3 will not show me the ear-Death Star-spider combo unless I put those exact symbols into my document source, or at least Unicode references that call for those symbols.  Because that’s what happens in a Unicode world: you get the glyphs you requested, even if you thought you were requesting something else.

The problem, of course, is that we don’t live in a Unicode world—not yet.  If we did, I wouldn’t keep seeing line noise on every web page where someone wrote their post in Word with smart quotes turned on and then just did a straight copy-and-paste into their CMS.  (Here we have a screenshot of text where a bullet symbol has been mangled into an a-rhone and an American cents sign, thus visually turning 'Wall-E' into 'Wallace'.)  Ged knows I would love to be in a Unicode world, or indeed any world where such character-incompatibility idiocy was a thing of the past.  The fact that we still have those problems in 2008 almost smacks of willful malignance on the part of somebody.

Furthermore, in most (but not all) of the text editors I have available and tested, I can type “Oy!” with the font set to Webdings and get the ear, Death Star, and spider symbols.  So mentally, it’s very hard to separate those glyphs from the keyboard characters I type, which makes it very hard to just accept that what Firefox 3 is doing is correct.  Instinctively, it feels flat-out wrong.  I can trace the process intellectually, sure, but that doesn’t mean it has to make sense to me.  I expect a lot of people are going to have similar reactions.

Having gone through all that, it’s worth asking: which is less correct?  Text editors for letting me turn “Oy!” into the ear-Death Star-spider combo, or Firefox for its rigid glyph substitution?  I’m guessing that the answer depends entirely on which side of the Unicode fence you happen to stand.  For those of us who didn’t know there was a fence, there’s a bit of a feeling of a slip-and-fall right smack onto it, and that’s going to hurt no matter who you are.


Browse the Archive

Earlier Entries

Later Entries