Let us suppose that I have a theme where I am designing among others forms. Let us suppose further that the form might have a submit button of class .submit. There are cases when the button is disabled (the form is not ready for submission) and when the button is not disabled. I can design the button like this:
.submit {
/*Some Rules*/
}
.submit:disabled {
/*Some Rules*/
}
However, if I know that the button will be inside a div and I want to style its parent based on the disabled property, then I need to implement a disable and an enable function and to style parentElement in those functions. Instead of that I would like to be able to define rules like this:
.submit < div { /*where < would mean parent*/
/*Some rules*/
}
.submit:disabled < div {
/*Some rules*/
}
Currently this is not supported.
Let us suppose further that I want to style the form based on the button's disabled attribute, to visually show whether the form is ready for submission. In this case I need to find the ancestor form tag (if exists) and style it whenever disable or enable is called. Instead of that, I would like to be able to do something like this:
.submit << form { /*Where << means ancestor*/
/*Some rules*/
}
.submit:disabled << form {
/*Some rules*/
}
Instead of this simple and straightforward way, currently we need to do something like this:
function disable(element) {
element.disabled = true; //Disabling the button
var p = element.parentElement; //Here we need to style p with Javascript
//Find the form element
var formExists = true;
while (formExists && (p.tagName !== "form")) {
if (p.tagName === "html") {
formExists = false;
} else {
p = p.parentElement;
}
}
if (formExists) {
/*Do something with p*/
}
}
function enable(element) {
element.disabled = false; //Disabling the button
var p = element.parentElement; //Here we need to style p with Javascript
//Find the form element
var formExists = true;
while (formExists && (p.tagName !== "form")) {
if (p.tagName === "html") {
formExists = false;
} else {
p = p.parentElement;
}
}
if (formExists) {
/*Do something with p*/
}
}
Despite appearance, disable and enable is not code-duplication, since we intend to add different styles. Off course, this code can be refactored somewhat, but it is ugly, difficult to maintain, hacky, not to mention the fact that it assumes that one calls disable or enable whenever the state of the disabled attribute needs to be changed. While all the problems shown above is solvable even without parent/ancestor selector, I would prefer to be able to implement the theme inside a .css file, without Javascript hacks, without assuming that whenever a button gets disabled disable is called and whenever a button gets enabled enable is called. Also, if this kind of thing could be triggered by CSS, then we could use automatically browser-level juices which could benefit performance.
An alternative is to have a class defined for a form, but then that class needs to be maintained programmatically along with the disabled attribute and things are not much better.
I believe I have proved in my question that such CSS rules would be superior compared to Javascript ui hacks from several points of view:
- parents and ancestors could be designed inside a single .css file
- developers would not have to worry about calling helper functions, nor about telling new team members those policies or documenting the usage of the theme
- there would be no need to write difficult-to-maintain Javascript functions to handle ui changes
- we could override the rules as we like with other CSS rules if needed instead of escalating the hacks to even bigger hacks
I know parent and ancestor selectors are not among the CSS features we can use, so I wonder whether the situation will improve. Are there known plans for this kind of feature? Are these scheduled for a future date?