The Ideals of Declarative Styling
What does it mean to specify styling the declarative way vs. the imperative way? A declarative definition is a statement of what you want to achieve, whereas, a imperative definition details the steps of how to do it.
1st Example
Say, what we want is a linear gradient.
The declarative way:
element {
background: linear-gradient(@params);
}It’s just a statement of the goal, not a list of instructions for realising it.
Compare this with the imperative style:
element {
background-image: -webkit-linear-gradient(@params);
/* For Chrome 25 and Safari 6, iOS 6.1, Android 4.3 */
background-image: -moz-linear-gradient(@params);
/* For Firefox (3.6 to 15) */
background-image: -o-linear-gradient(@params);
/* For old Opera (11.1 to 12.0) */
background-image: linear-gradient(@params);
/* Standard syntax; must be last */
}To achieve the same goal, you add a bunch of details to make sure your intent is recognised by each vendor. Why would you have to do this? Because the processor of your style sheet is not smart enough.
2nd Example
Now let’s say we want to give some text a gradient color.
The declarative ideal is:
text-element {
color: linear-gradient(@params);
}Since as of now there’s no support for this feature, the browsers won’t recognise what you want. You would have to specify a work-around:
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-image: -webkit-linear-gradient(@params);
This list hand-holds the browser, takes it step-by-step through the process of achieving the same result: some text with gradient color — and the browser still doesn’t know that “having a gradient background, clipping the background based on the text, then setting the text transparent” achieves the same visual result as “setting the text color to a gradient”.
3rd Example
Say, you want to hide the caret (the blinking prompt) in a text field. Currently there’s no API for styling the caret independently, but again there’s a hacky work around:
- Set the text to transparent, the caret becomes transparent with it.
- The text is now invisible, we’d better do something about that!
- Alright, add a text-shadow with zero offsets (in exactly the shape of the text) and the original text color.
Why can’t we just say the following?
input {
caret-color: transparent;
}Or even:
input {
caret-color: linear-gradient(@params);
}Ideals
But browsers are getting smarter. They may be dumb now, but they should be less dumb in 3 years. That’s why prefixes gradually get dropped as support becomes more wide-spread.
Then your old style sheets are left with a bunch of unnecessary “imperativeness”, unless you update them regularly. Manually checking what’s the latest and greatest in browser support can be tedious.
What’s the solution? A processing engine should do this for you. It should be more than just an auto-prefixer. You write once that you want gradient text, it figures out how to give you gradient text, based on the state of browser development of that time.