Wysiwig is hard #4, editing StyleSheets...

Editing stylesheets in a wysiwyg
editor can be hard. For multiple reasons:

stylesheets are of three different kinds: embedded into the
document through a <style> element, linked
through a <link> element, or imported from
another stylesheet (and nesting is possible) through an @import
rule. In html5, the possibility to have embedded styles anywhere in
the document adds another layer of complexity, in particular in the
case of presence of the scoped attribute... I must
admit BlueGriffon is not ready for that yet, I have not resolved all
the technical issues related to scoping. In particular, the
specificity of scoped styles is unchanged and I am not sure this is
coherent with the spirit of the CSS Cascade. This may have deep
implications on the wysiwyg editing side but an ID selector's
specificity should probably be added to all scoped styles.

Listing all stylesheets applied to a given document is simple
using one single CSS OM call. Determining if a stylesheet is
embedded, linked or imported is done through the parentStyleSheet
and ownerNode attributes on CSSRule
and StyleSheet interfaces.

Serialization of a stylesheet is painful. I had to write
thousands (yes, really) of lines of JS to handle that because
unknown CSS rules are not preserved by the browsers' style
engines. Even if they were, an editor just cannot consider a
vendor-prefixed property has to be output unchanged. A style
change by the user could affect vendor-prefixed styles stored as
unknown rules in the CSS OM...

adding a given style to a given element is hard; not only you
must find all the style rules that apply to the element for the
property you want to edit, but you also need the specificities of
those rules. When you have the list of couples (rule, specificity
of the rule), you must find the rule of highest specificity. If
that rule is editable, i.e. if the stylesheet can be modified by
the application, then you must create a style rule or a style
attribute of a high enough specificity and/or importance
overriding the current style. If the stylesheet is not editable
(file not writable, remote resource), then you may have to create
a new embedded or linked stylesheet (or use a style attribute) to
apply the style you want. I don't even want to think about the scoped
styles case for the time being, it's a nightmare.

html5 defines a new
presentational attribute on all elements: the
hidden attribute... It is not entirely clear to
me if a true value of that boolean attribute should map to the CSS
display: none; style or use another mechanism to hide
the element. In the case of the former choice, this will add
another layer of complexity to the editing algo for the display
property. Furthermore, in the case what's the position of the hidden
attribute in the CSS cascade? I think the html5 author's
spirit make it override all other styles. But that's not how the
Cascade works, giving a very low specificity to presentational
attributes. Should the hidden and the style
attributes have the same specificities? Should hidden
exist at all? I don't think it should. It's presentational and we
have the display property anyway. The only reason why it should
exist could be an accessibility reason, voice browsers often using
the DOM and not the CSS OM. By the way, the spec says "When
specified on an element, it indicates that the element is not yet,
or is no longer, relevant". Does it imply that styles contained in
a <style hidden> should not apply any more? In other terms,
does it disable the stylesheet? This hidden
attribute is a can of worms, underspecified, and it will raise
tons of technical issues in the near future.

editing an embedded stylesheet is a pain. I'm sure you thought
this should be the easiest case. No external file or remote
resource, everything is inside text nodes. Simple, eh? It's not.
It's not if you want the dialog editing such a stylesheet to be
non-modal... Let me explain: if the dialog is not modal, then all
changes to the styles are immediately applied. Let's suppose my
embedded stylesheet contains only p { color: red; }
and that I want to change that color to blue. I have two choices
depending on the frameworks I am using:

first case, I have access to an abstraction layer allowing me
to tweak directly the source of the stylesheet; then I can
change the red into a blue, and replace the textual contents of
the style element by the new stylesheet

I have only access to the CSS OM; then I can change the
property value in the CSS OM, serialize the stylesheet and then
replace the textual contents of the style element

But in both cases above, I have a serious problem: the stylesheet I
was editing does not exist any more! The style rule I was editing
does not exist any more! They were replaced by a new stylesheet and
a new style rule after parsing of the new textual contents... So if
I kept a reference to the stylesheet and style rule I edited, they
suddenly get a null ownerNode, my whole UI still shows style objects
that are now only references to objects unrelated any more to the
document. That implies that every style change, I repeat every style
change, in an embedded stylesheet from a non-modal UI should totally
reflow the UI or at least, reassociate all UI to new style objects
that did not exist before... Urgh, to say the least.

Editing styles in a wysiwyg
editor is not, as I heard it during a chat a few months ago, "only
a matter of a few calls to the CSS OM". It's painful, expensive
both in terms of performance and footprint, sometimes tricky in terms of UX and requires stuff that the
CSS OM does not implement . It can be really hard.

Comments

The only way the hidden attribute differs from rolling your own .hidden { display: none; } class is that the theoretical UAs that don't support CSS (including theoretical assistive technology mappings that don't pay attention to computed style; real ones do) are supposed to know to hide stuff that has the hidden attribute.

Basically, if you want to argue against the hidden attribute, you need to argue against the principle that CSS is optional.