CSS Layers - Fork off CSS Features thread

In the CSS Features thread I threw out the idea of CSS layers. Not much commentary on them, possibly due to thread length. In spare time I’ve been mulling over what they mean and what they could be used for and now that I think about it they might be a very, very powerful tool. This is what layers do in brief:

  1. They create a new cascade context.
  2. They separate styling rules and styling patterns.
  3. They solve a few longstanding problems in CSS in a backwards compat way.

So that no one needs to look at the original post I’ll go back over what I suggested with some additional information.

First, a layer is an entity property like a class or id. If the layer is not specified then the entity is on the root layer.

Unlike classes and id’s, entities inherit their layer from their parent. Like id’s an entity can only have one layer. Like classes multiple entities can have the same layer.

Each layer has its own cascade scope. That is the most important trait of layers. If an entity is assigned a layer it will not inherit anything from it’s ancestors and it will no longer have an effect on them.

Assigning an entity to a layer affects content around it in the same way as if the entity was set to absolute or fixed positioning. Also, like absolute positioning, the default position of a layer entity is the computed position it would have had.

Layers have global properties that apply to the layer. These are tenative names - please let me know if you have a better name.

  • interactive (yes/no): Are entities on the layer interacted with by the user. This allows the designer to designate a layer with visual effects in front of elements the user wants to interact with. For example, placing a transparent animated gif of animated and tile it over the entire viewport.

    Elements on a non-interactive layer are removed from the tab-index, cannot receive focus do not fire mouse events of any sort.
  • z-index: The z-index of layers is relative to other layers, not to elements. If an element is on a layer with a z-index of 0 and has a z-index of 1000 it will still be displayed behind the elements on a layer with a z-index of 1.
  • opacity:On the layer as a whole. If an element has an opacity of its own this is applied relative the layer opacity. An element with opacity .5 on a layer of opacity .5 would have .25 overall opacity.
  • cascade:How the layer cascades
    [list][*]normal: Default, the layer follows normal CSS rules.
  • non-positional: Rules inheritance applies (div.class declarations inherit div declarations) but positional inheritance does not.
  • positional: Inheritance is by position only (div.class does not inherit from div meaning it is treated as if it had its own tag. It would inherit from a div that contained it.
  • none: Cascading does not occur on the layer. Admittedly this will be more useful in scripting than in design.[/list]
  • origin: The location of position 0,0 in the viewport. The root layer’s origin is top left so existing position schemes will work normally. The other options are top center, top right, middle left, middle center, middle right, bottom left, bottom center and bottom right.
  • anchor: Similar to the above, this is where the elements on the page anchor from.
  • ordering: How elements are resolved.
    [list]
  • top: The long standing default of CSS is to put elements on the top of the layout and work down. This option continues to be the layer default.
  • bottom: Entities start from the bottom and go up. If the root layer is set to this the scrollbars will start at their lowest position.
  • left: Entities nest left to right.
  • right: Entities nest right to left.
    [/list]
  • overflow: Can the layer overflow the viewport, creating scrollbars. Having this be a layer property eliminates the need of creating a container div for everything on the layer and setting it’s overflow property.

And that’s all I’ve thought of for now, but I’m sure there’s other possibilities. Here’s what style sheets would look like.

First, layers need their own character. We have # for ids, @ for media rules, . for classes, * for global declarations. That leaves ~ or $ Of these I think ~ is best.


/* The properties of the root layer can be changed with this. 
the settings below work more nicely with languages which
normally go bottom to top and right to left in print */
~ {
    origin: bottom right;
    ordering: bottom;
}

/* An example layer for putting a decorative smoke glass pane
in front of the contents. */

~glass {
    origin: center, center;
    interactive: no;
    overflow: no;
}

~glass div {
    background: url(glass.png) center center repeat;
    z-index: 1;
}

/* These are equivalent */

* { }
~ * { }

/* And to set new defaults for all entities on a layer */

~glass * {}

/* Layers don't inherit - that's sort of their point. But occassionally
making a statement about all layers will be useful. To do that */

~~ div {
/* properties of all divs on all layers. */
}

/* The :not psuedo elements applies to layers */
~~:not(glass) div {
/* property for divs on all layers but the glass layer */

Ok. Please post questions, comments, concerns and merciless mocking. :slight_smile:

Your idea gives me somehow a bit of a “inventing the wheel again” feeling. So far I don’t see any real advantages.

I am with donboe here, I don’t see the point. It seems like it would confuse things more.

Are entities on the layer interacted with by the user. This allows the designer to designate a layer with visual effects in front of elements the user wants to interact with. For example, placing a transparent animated gif of animated and tile it over the entire viewport.

Why would somebody put an image that moves, on top of words, links and other images. Not only does this scream 1998/1999, it would be terribly distracting.

z-index: The z-index of layers is relative to other layers, not to elements. If an element is on a layer with a z-index of 0 and has a z-index of 1000 it will still be displayed behind the elements on a layer with a z-index of 1.

This almost makes it sound like you want to build a psd file with css…

Hmm… I’ll try one last time. In a professional art program such as Photoshop the image is divided into layers. Layer order does determine what goes “in front” of what, but that is not the only thing they do. It is not even their main purpose since you can change the order of elements in the drawing at any time without using layers.

Layers instead set common properties for the objects that they contain. They allow the designer to affect a group of objects in one action. By locking layers temporarily they can also get to objects that lie behind other objects and edit them.

This proposal is conceptually the same as that.
Layers are independent from one another in cascade sequence - CSS rules set on one layer do not carry over to another layer.
Layers are able to have rules that would adversely affect the layout of the rest of the page - having a layer render it’s elements starting from the bottom of the viewport and working up for example, or if you are doing a timeline page having a set of elements that render from left to right.
Layers can be locked off from the user so that they don’t affect the user’s ability to touch the other elements. The example I gave was animated snow falling in front of everything on the page - but you could also have smoked glass in front of the page as long as it’s subtle. This is downright not possible in current CSS.

The layers are about rules organization as much as they are about positioning. It would be nice to have an element start back at the rendering defaults without having to undo every rule it might have picked up because of where it is in the DOM. This becomes particularly bothersome in javascript - if you move a block of the DOM from one spot to another its appearance can change as it inherits rules you didn’t expect it to inherit. With layers that issue can be addressed by putting the element onto a new layer.

Layers are not divs. This isn’t a proposal to go back to Netscape Navigator 4. The HTML side of the markup is

<div id=“header” class=“padded” layer=“navigation”>

Not a ‘layer’ tag as was seen in Navigator 4. I don’t think anyone sane wants to go back to that.

Photoshop and the web are two different worlds, which should not be combined. We already have z-index, which are basically these. Why make things more difficult? Poorer coding, etc.

Layers instead set common properties for the objects that they contain. They allow the designer to affect a group of objects in one action. By locking layers temporarily they can also get to objects that lie behind other objects and edit them.

…what

Layers are able to have rules that would adversely affect the layout of the rest of the page - having a layer render it’s elements starting from the bottom of the viewport and working up for example, or if you are doing a timeline page having a set of elements that render from left to right.
Layers can be locked off from the user so that they don’t affect the user’s ability to touch the other elements. The example I gave was animated snow falling in front of everything on the page - but you could also have smoked glass in front of the page as long as it’s subtle. This is downright not possible in current CSS.

You provided css rules, now code up a mock page. The source sounds nasty…

Layers are not divs. This isn’t a proposal to go back to Netscape Navigator 4. The HTML side of the markup is

<div id=“header” class=“padded” layer=“navigation”>

Not a ‘layer’ tag as was seen in Navigator 4. I don’t think anyone sane wants to go back to that.

ick

positioning?
Are you saying make the word “THIS” appear like?
S
I
H
T
but read normally?

How do you reset the cascade rules and start again? You don’t.

Exactly so how is this way different?

How do you put a watermark at .05 opacity in the foreground of the page? Again, you don’t if you have a form on that page because you won’t be able to click on anything.

The web doesn’t need watermarks, if you do, you can tile a bg. Or link to a doc/pdf/flash paper which has this. I have never seen a watermark on top of words, unless the person messed up

I don’t quite get it either.

Explain how you would build the DOM in reverse order then, with the first element rendered at page bottom and working up (as is natural in chinese and several other asian languages). You can’t.

How do you reset the cascade rules and start again? You don’t.

How do you put a watermark at .05 opacity in the foreground of the page? Again, you don’t if you have a form on that page because you won’t be able to click on anything.

I can see a point to doing any of these.

Since there’s more detail in the first post…

* interactive (yes/no): Are entities on the layer interacted with by the user. This allows the designer to designate a layer with visual effects in front of elements the user wants to interact with. For example, placing a transparent animated gif of animated and tile it over the entire viewport.

Maybe I could think better if something way less annoying than an animated gif or smoke or fog or whatever needed to be placed in front. Have you ever worked with radioactive material in a lead box? You put your hands through some attached lead gloves and have to manipulate the element while looking through the glass. It’s surreal to say the least.

In any case, today to make things manipulatable, there’s negative tabindex.

  Elements on a non-interactive layer are removed from the tab-index, cannot receive focus do not fire mouse events of any sort.

Currently anyone who is not a focusable element, or does not have a tabindex set, is not part of the tab index anyway and do not fire mouse events unless you put them there.

* z-index: The z-index of layers is relative to other layers, not to elements. If an element is on a layer with a z-index of 0 and has a z-index of 1000 it will still be displayed behind the elements on a layer with a z-index of 1.

If you don’t mention z-index, this is what happens: a parent sets the stacking context. Children sit on top. If another element comes along, its children, even if they are at the same level, are only “high” compared to their parent.
It’s only because parents who come later in source are themselves children of the body element and so have a slightly higher stack than parents who came before and so when you pull a later-source element “up” with a negative top margin, it’ll cover an element who came earlier in source (assuming that element’s not “positioned”). They had to make some rules on what happens when rule collide… this was their compromise. And older browsers had a lot of trouble with it (FF2, IE6/7 etc).

And we have the problem of setting a z-index of a gazilion and another element with no z-index still sitting over it: Flash sitting in it’s own “window” in IE. I’m not sure anyone thought this was good.

* opacity:On the layer as a whole. If an element has an opacity of its own this is applied relative the layer opacity. An element with opacity .5 on a layer of opacity .5 would have .25 overall opacity.

This is how it is. To a child, the opacity of a parent (say parent is set to anything less that 1) == 100%. A child with half opacity is starting at the lowered opacity of its parent to begin with.

* cascade:How the layer cascades
      o normal: Default, the layer follows normal CSS rules.
      o non-positional: Rules inheritance applies (div.class declarations inherit div declarations) but positional inheritance does not.
      o positional: Inheritance is by position only (div.class does not inherit from div meaning it is treated as if it had its own tag. It would inherit from a div that contained it.
      o none: Cascading does not occur on the layer. Admittedly this will be more useful in scripting than in design.

If you’re going to remove one of the basics of what CSS is, you don’t really have CSS, why use it?
You remember how difficult it was for browser vendors to get right what goes on now, yes? I can see them straining their little engines for 4 different “versions of CSS”.

* origin: The location of position 0,0 in the viewport. The root layer's origin is top left so existing position schemes will work normally. The other options are top center, top right, middle left, middle center, middle right, bottom left, bottom center and bottom right.

Well, the right top is what you get with a rtl page, but if browsers knew what a bottom really was (they don’t, this is why we can’t use auto-margins to center an element vertically) this could be cool.

* anchor: Similar to the above, this is where the elements on the page anchor from.
* ordering: How elements are resolved.
      o top: The long standing default of CSS is to put elements on the top of the layout and work down. This option continues to be the layer default.
      o bottom: Entities start from the bottom and go up. If the root layer is set to this the scrollbars will start at their lowest position.

Again browsers will have to know what “bottom” means, and there will always be at least two bottoms: viewport bottom and document bottom.

      o left: Entities nest left to right.
      o right: Entities nest right to left.

Not understanding this. We want CSS to “look” like it’s nesting elements, but not really?

* overflow: Can the layer overflow the viewport, creating scrollbars. Having this be a layer property eliminates the need of creating a container div for everything on the layer and setting it's overflow property.

Uh, wait. If you don’t have some box with overflow property set on it, who makes the scrollbars? Currently it’s whoever is getting overflowed. You want scrollbars to appear randomly on some other element if someone overflows… who are they overflowing again?

Currently anything sticking out of the viewport makes scrollbars (unfortunately even absolutely-positioned elements to the right or bottom do this).

Nothing in the original post isn’t restated here, so don’t worry about it.

Layers isn’t merely about positioning, though that is some of it. It’s about context and behavior grouping. But using your own example

Say you have a menu div. When visible it should always be in front of other elements. Now if you have a stack of divs behind it each time you change the z-index of those elements you have to go back and make sure your menu div still has the highest z-index.

Whereas with layers you’d give it a z-index of 1 and not worry with the elements not assigned a layer since they’ll have the root layer’s z-index of 0.

It is true that you would have to make sure your top element has a z-index over all the other layers, but in practice there may be hundreds of elements in a page there will rarely be more than a few layers.

Also to your example, if you put a div in front of another div there is no current way of clicking on elements on the background div even if the foreground div has a low opacity or is nearly transparent. With layers you can do this - just set the foreground layer to non-interactive.

That’s just the start. Load ordering and changing the origin are completely outside the realm of current CSS possibility, nor are they easily emulated.

Go back and read the post thoroughly. Your post reads to me like you saw the word “layer” and decided to reply without reading anything else.

Where do I find the original post? But aren’t layers already existing? Place two divs on top of eachother and you have layers or do I see this wrong?

Explain how you would build the DOM in reverse order then, with the first element rendered at page bottom and working up (as is natural in chinese and several other asian languages). You can’t.

Chinese read from bottom to top? That’s news to me, I thought they read from top to bottom. There is a reason why they say, for example Hebrew pages, “do not screw with CSS to get the elements in the order you want”. Instead they insist you use direction on your (logically-ordered!) DOM. The user agent sets the direction based on logical DOM order, not CSS. This is not something one should do with the presentational layer.

It seems Microsoft was ahead of the game when it came to CJK… but there’s hope for the future.

How do you reset the cascade rules and start again? You don’t.

If you are trying to solve a problem, then you’ll have to first state why it is a problem. http://www.joelonsoftware.com/articles/fog0000000037.html

I don’t fight the cascade. I use to to let me stay a lazy coder. If you don’t want rules on something, don’t set them on them. It’s like

How do you reset the properties of an object who’s inheriting from a class?

Why is that object built from that class then? But that aside, sure, you can individually revoke every single style if you want. I did it once when making a fun site for IE6 users versus everyone else. BUT, if you have to do that in real websites, you’re writing it wrong.

How do you put a watermark at .05 opacity in the foreground of the page?

A watermark covering a web page? Seriously?

Layers can be locked off from the user so that they don’t affect the user’s ability to touch the other elements. The example I gave was animated snow falling in front of everything on the page - but you could also have smoked glass in front of the page as long as it’s subtle. This is downright not possible in current CSS.

Smoke, a cloud, a sheet, fairies… I think you’re daft if you expect human beings to read through that. Again, I’m assuming this is for web pages, which are text, and not a game or Flash App (catch the monkey in the fog with your mouse kinda thing). You expect me to fill out an insurance form looking through fog? I’m already lost at the legal jargon.

What I’m trying to see is why it’s a good idea to have “stuff” in front of a web page. How does something visually in front of any text (you do put text on web pages right?) NOT get in the way of someone reading it? If you put snow or fog or some other stuff in front of my text I sure as heck am not going to be all like “but it’s cool because I can still select the text and type into the forms!” because no, that’s not cool. It means I need a screen reader to access your page. It may be a technological “problem” of CSS, but it’s one nobody in their right minds wants to “fix”. I’ve heard the Japanese were working on a Smell-O-Vision for web sites though.

Layers are able to have rules that would adversely affect the layout of the rest of the page - having a layer render it’s elements starting from the bottom of the viewport and working up for example, or if you are doing a timeline page having a set of elements that render from left to right.

Explain to me how I can’t have things go from left to right?? I need some new technology to do this? Certainly if I have something I’ve built “near the top”, moving it to start from the viewport bottom on up would be… disasterous. If you want to hide something, use display: none. If you just want the page jumbled and unreadable, remove the doctype and re-feed the code through Sea-Monkey WYSIWYG.
However you might be interested in something coming up in CSS3: so far it’s called “flex-box” and basically your container is “box” and you can then just say what the children have to do (no floats, no other funky display states, just stuff like orientation and direction and whether they fill remaining space or not etc).

The layers are about rules organization as much as they are about positioning. It would be nice to have an element start back at the rendering defaults without having to undo every rule it might have picked up because of where it is in the DOM. This becomes particularly bothersome in javascript - if you move a block of the DOM from one spot to another its appearance can change as it inherits rules you didn’t expect it to inherit. With layers that issue can be addressed by putting the element onto a new layer.

This almost sounds like… separate documents on a single web page. Of course, I don’t grab huge chunks of DOM with Javascript and randomly insert it anywhere. I suppose I’d kinda expect anyone who does that without thinking twice to get weird CSS results. If I turn a human inside-out, I’ll prolly get the same thing. Ew.

So this is some sort of CSS version of… iframes? iframes without the frames?

You should see how they get a browser to report back stuff to accessibility software. It’s so amazingly complicated. Even with our ordinary simple websites. Seriously, Firefox makes “dead accessibles” and random errors can give strange random error messages to AT that take hours of crawling through Mozilla’s specs just to try to figure out where the browser and the OS and the windowing system and the AT miscommunicated. With heavy DOM manipulation via Javascript this gets much, much, much more complicated… and we’re doing it (DOM manip with JS). Now more DOM manip and placement and where does the caret focus go and which part does the AT pay attention to and how do users with non-popular interfaces interact with all this?

If you built a system the way you’re describing and then got one browser on one OS to work with one common type of Accessibility Technology, hell you’d win a prize for… something. One with money. Because it would be such an awesome feat of engineering that the browser vendors and the AT people would bow down at your feet and wash them with their tears and dry them with their hair.

Ok maybe I exaggerate a little. I either am missing what you mean, or it’s something that one would never want to add to web sites (maybe when we get into the whole 3-d stuff like I saw in Iron Man 2 the other day… I imagine the accessibility for that stuff will be wildly different from what we have today anyway… and by then, they won’t be “web sites”).

Touch: yes. The negative tabindex trick is in fact mostly used for Javascript to have something to grab focus() from.

* expand: The element expands, or expands proportionately, to the limit of the area allowed. THIS IS NOT THE SAME AS 100%  Setting "width: 100%" on an element contained by an element with padding causes the outer element to be pushed out. Setting "width: expand 100%" will expand the element to the limit of the available space, and if the parent's padding is increased the element will shrink correspondingly.
* collapse: The element collapses to the minimum area needed for it's contents. This is CSS's current behavior incidently.

Blocks expand width-wise by default, but collapse height-wise by default. Wishing for 100% height expansion is something we’ve wished for for some time.
Inlines, floats and absolutely-positioned boxes collapse their height and width by default.
So width is taken care of but height isn’t. Many developers would want an expanded height option (along with vertical centering).

Positioning, particularly center positioning, is a pain in the tail in css, and the only valid criticism the table layout grognards have (table layouts can do flex vertical centering easily, CSS flat out can’t). These three properties address this long standing issue.

Center is the left to right center. Middle is the vertical top to bottom center.
Anchor is the point on the element that lines up with the coordinates given by the top, bottom, left, right, and new middle and center properties. If this seems unnecessary remember that we may not want the object to line up on the center but rather sit on the center line. This can be done with negative margin tricks and calculations, but those are counter-intuitive and easy to screw up (or get screwed up when the screen is resized).

I have no problems centering horizontally, but vertical-align is much-asked for. Your options are: hacks, display: table, a real table, and sometimes inline-block.

The new CSS3 flex-box proposal will deal with alignment in every way possible, for blocks too!!! which will be awesome. 10 years from now, lawlz.

The idea of adding another attribute to elements is pretty evenly panned as bad, and I had my doubts but it shot it out there for discussion. The properties themselves are things I’d like to see, so let me go over them again but this time in the context of being element properties or settings of existing properties.

These are universal properties that can be applied to any element unless otherwise noted.

Before we continue I’d like to state that I do appreciate the feedback, even the more negative comments.

Touch
Can the element (and it’s children) be “touched” by the mouse. I’ll be upfront and state this is the sort of thing javascript is going to make use of more than flat css style sheets. I could see it used to apply an overall tinting to a page (think green filter of Fallout 3). I come from a theater background, and I think of an element doing this in the same way I think of a light effect. To be effective it must be very subtle.

Anyway, when an element is positioned in front of another, the element in the back current has no way of receiving events. Touch addresses this by allowing an element to become invisible to the mouse.

Yes, this has the potential to be as annoying as the blink tag or worse if misused, but it could be used very effectively.

[list][]all: The element is touchable as normal.
[
]children: The children are touchable, the element itself is not.
[*]none: The element cannot be touched, nor can its children.
[/list]

Height, Width
Both these properties get two new settings.

[list][]expand: The element expands, or expands proportionately, to the limit of the area allowed. THIS IS NOT THE SAME AS 100% Setting “width: 100%” on an element contained by an element with padding causes the outer element to be pushed out. Setting “width: expand 100%” will expand the element to the limit of the available space, and if the parent’s padding is increased the element will shrink correspondingly.
[
]collapse: The element collapses to the minimum area needed for it’s contents. This is CSS’s current behavior incidently.
[/list]

If you want the body to expand to fill the viewport
body { height: expand; width: expand; }

Middle, Center, and Anchor
Positioning, particularly center positioning, is a pain in the tail in css, and the only valid criticism the table layout grognards have (table layouts can do flex vertical centering easily, CSS flat out can’t). These three properties address this long standing issue.

Center is the left to right center. Middle is the vertical top to bottom center.
Anchor is the point on the element that lines up with the coordinates given by the top, bottom, left, right, and new middle and center properties. If this seems unnecessary remember that we may not want the object to line up on the center but rather sit on the center line. This can be done with negative margin tricks and calculations, but those are counter-intuitive and easy to screw up (or get screwed up when the screen is resized).

Examples


/* Element in the middle of screen */
#centered {
  position: fixed;
  anchor: center middle;
  center: 0px;
  middle: 0px;
}

/* Element in middle of page itself (which may require scrolling to see it).
#centered {
  position: absolute;
  anchor: center middle;
  center: 0px;
  middle: 0px;
}

/* Watermark in printout header. Note the viewport
 * of a printout is the paper, so the element will
 * be repeated on all pages. Might have the media
 * tag wrong, but this is for example.
 */
@media: print {
  #watermark {
    z-index: -1;
    anchor: top center viewport;
    center: 0px;
  }
}

I think I understand the basic idea that you want to create blocks of content that are independent of the cascade so that they can have their own rules applied consistently without interference.

This means that you could take an element and place it anywhere in the page and it would still display exactly as it did before (assuming you made room in the page for it.)

That would allow you to create “third party” code say for a drop down navigation that could be inserted into a page without worrying what rules were cascading down in that page.

So what you are essentially making is something called "“Un-cascading Style Sheets” :).

I guess that in some cases that would be useful in that you could create modules for a site and the site owners could just drag and drop the modules into places where they need them and they would work. I have had clients ask for that requirements on some newspaper sites where they create articles and stories and want to insert then in any column and in any place where there is room. They obviously can’t do this because of the cascade and the existing rules applied to elements in that situation.

Unfortunately I don’t think it would be feasible to design something like that as the overheads would seem to be enormous because instead of one basic DOM tree you are defining thousands of possible dom trees and the calculations that presently are handled on just the one tree will have to be made for every one of these elements that you add.

We already know that CSS can’t manage to style a parent based on a child because the overheads are too massive so I’m guessing that setting multiple islands of content would be a no go from the start - but then I’m not a programmer either so I may be wrong. :slight_smile:

To clarify I think that you are looking for the same effect that you would get had you inserted iframes into your page where you get independent sections of content that are not part of the current cascade.

I am pretty new to all of this so most of what has been said has been lost on me. It would probably resonate with me more if I could see a working example of something using layers that couldn’t be done any other way. Could you knock together a basic example or point me to a site where this is already being used.

you mean behaviour from something like PowerPoint or IMPRESS where every object (drawing, text) has it’s own layer? but all those layers combined let you make powerful presentational choices and “interface”?

Maybe it’s the language barrier but I don’t know how I can make myself more plain than I already have. I’m sorry.

But that’s why i said aren’t layers already existing? Maybe not by name, but still. If I woul like to have some kind of elements behind my navigation for layout purpose I can already do so! So what advantage, in such a case, would it have to have layers next to classes and id’s.

You answered your own question. This is CSS. Layout is what it’s about.