Marking style properties as "required" + groups of styles

Hi there, I've got something for the CSS3 'ideas' pile.

I've recently developed a site in which the lower levels of navigation
(lists) are hidden until a parent (a <li>) is :hover'd over. The
effect (commonly called "Pure CSS Menus") is nice. A degraded, CSS1
supporting version is provided in the same stylesheet by using
CSS2 selectors (namely ">") to hide the newer content from old
browsers. However, when testing using Konquorer 3.1.4 (the latest
version you can get running on Windows+Cygwin, not actually the
current version at all) I discovered a problem.

This version of KHTML supports the ">" selector, so applied the
collapsed menu styles, but didn't support :hover on all elements.
Thus, the menus displayed collapsed, but the UA was unable to show
the content when hovering.
The CSS spec does not require UAs to only implement complete specs
(else we'd still be without CSS1...) but when support of the same
level of CSS varies in a UA, I would like to avoid resorting to any
kind of JavaScript sniffing to more finely control implementation. It
extends development time in terms of otherwise unnecessary research
and adds to the workload of maintenance over a period of years for the
site's lifespan.

Hence, this proposal, (which comes in two parts).

1) Introduction of a "!required" declaration. This would be added to the
CSS syntax in the same way as the "!important" declaration is used at
the moment. It could be specified on a property-by-property basis, or
to entire styles.

e.g.

foo {
  background-color: #F00;
  vertical-align: bottom !required;
}

In the above style, for a user-agent to apply the style it must
support all properties marked as required. If a UA does not support
'vertical-align' (as in this example) then it should not apply
background-color either.
Conversely, if it did not support background-color but did support
vertical-align, then the style should be applied with the property not
marked as required unrendered.

A larger example:

foo.watermark {
  display: none;
}

foo.watermark {
  display: block;
  position: absolute;
  bottom: 0;
  right: 0;
  opacity: 10% !required;
}

In this case, we have an element foo (which lets say is an image that
the author wants used as an overlaying watermark on their site).
However, if the UA doesn't support CSS3 opacity, then the watermark
will obscure the content of the page and make it unusable.
The first style hides it completely from all UAs, and the second
should only be implemented by a UA that understands 'opacity'. Thus,
the author has no worries about his content being obscured by
presentation.

Part 2) A way of declaring 'groups' of styles and requiring entire
styles within a group. In my original use case, the problem arose from
an unimplemented :hover style. However, this was a different style
altogether from that which was responsible for transforming the menu
into its initial, collapsed state. It's that collapsing rule that
needs to be ignored if :hover is not implemented, not the :hover rule
itself (or any property within it).

I have a less solid idea about how to declare this syntax, so consider
this as a starting point only.

/* a group of styles */
@group {

  /* the first style in the @group */
  foo bar {
    display: none
    background-color: #0F0;
    color: #000;
  }

  /* the second style in the @group - this is required */
  foo:hover bar !required  {
    display: block;
    position: absolute;
    top: 0px;
    left: 1em;
  }
}
...

In this example, a child element will only be displayed if its parent
is hovered over. However, the :hover rule is marked as required.
Should the UA not understand the :hover rule (or if that rule fails as
a result of any contained property that is also marked as required)
then everything within the @group should be ignored (therefore "bar"
will not be hidden, and some other styles elsewhere can specify a
degraded presentation).

For my own use-case: The CSS for displaying the lists as popup menus
would be wrapped within a @group { } and failure on a "li:hover"
rule would also fail everything related to the collapsed menu system and not
make the content inaccessible.

N.B.
a) If a style is marked as !required and is not contained within a
@group, then the entire stylesheet should fail and be ignored.

b) If a style is marked as !required, and contains a property that is
marked as !required which then fails, then the entire style should
fail.

This !required syntax would allow a user-agent to perform a 'self
assessment' on what to apply, rather than any grotesque system of
conditional styles based on User-Agent names/Ids (c.f. Microsoft's
conditional comments extension to HTML).

I see no reason why !required could not also be applied to a @group
(@group !required { }) and have the same failure inheritance applied to
it as any other property & style relationship.
Whether nesting @groups would be taking the idea too far away from
interests in simpler syntax I'm less sure.

Feedback is greatly appreciated. Kind Regards,

Ben Ward
-- http://www.ben-ward.co.uk

Received on Wednesday, 22 December 2004 00:42:10 UTC