CSS Reworked
The language of cascading style sheets has a number of well-known
deficiencies and inconsistencies. Fortunatelly, there is a way to
fix lots of them with minimal changes to syntax.
It's really misleading that hyphens in properties' names are used both
as substitutes for whitespace (as in vertical-align
) and
as subproperty delimiters (as in padding-left
), we favour
dots as subproperty delimiters (border.top-left-radius
).
CSS files consist of at-rules (like @import
, @media
and @font-face
), and unprefixed rules. We'd gain more
consistency and natural syntax for scoped rules by requiring them
to start with @rule
, just like this:
@rule div.sidenote {
font: smaller;
color: rgba(0%, 0%, 0%, 0.9);
@rule strong {
font.weight: 300;
}
}
It would be also nice to fix once and for all syntax for interpolation
of expressions (in scripting language, JavaScript by default), preferably
square brakets. Assuming the scripting language is CSS-units-aware, we
can dispense with calc(·)
, var(·)
and attr(·)
in
favour of stuff like [1em + 5px + additional-width]
.
You probably know about how <li>'s
are styled in classical CSS2+:
li:before {
content: "•";
padding-right: 8px;
}
But you cannot really put HTML content there, and interpolation works
ugly. We propose the following syntax:
@rule li:before {
<span>•<sub>[counter]</sub></span>
padding.right: 8px;
}
So, just put HTML template in the beginning of the body of the rule.
To improve consistency yet more let's deprecate the display
property in favour of such templates involving layout tags
(<none/>
, <tabstop/>
,
<run-in/>
, <inline/>
,
<block/>
, <inline-block/>
,
<flex/>
, <inline-flex/>
,
<float/>
, <overlay/>
,
and all the grid stuff):
@rule div.remark {
<run-in>[content]</run-in>
font.size: smaller;
}
We also require fixing display mode for proper HTML elements (i.e.
the ones with specified semantic meaning, not fixed presentation)
before non-inheritable properties (the ones like width
)
can be set on them. We want to forbid setting width
of a <div>
in by a rule which is not aware that
this particular <div>
has display mode allowing
this property.
Custom Element Definitions
(This section is heavily influenced by ideas from Riot.js.)
The last and most interesting thing we want to add to CSS is the
element definition rule. Take a look at the following example, which is port of an example from Riot.js:
@element Timer(start : Nat) @extends VisualElement(alt: [content]) {
<block class=timer-box>
<p>Seconds Elapsed: [time]</p>
</block>
@rule block.timer-box {
max-width: 300px;
height: 100px;
line-height: 100px;
margin: 0 auto;
border: 1px solid rgba(64, 139, 194, .5);
border.radius: 6px;
text-align: center;
color: rgba(64, 139, 194, 1);
background: white;
}
@rule p {
margin: 0;
}
this.time = attr.start
tick() {
++this.time;
}
var timer = setInterval(this.tick, 1000ms)
this.on('unmount', function() {
clearInterval(timer)
})
}
The example defines a new visual element <Timer/>
. The definition
makes use of a combination of HTML (including presentational tags for we're on a visual
media), CSS and JavaScript and shows they compose well.
The difference from original Riot.js definition (which we consider
to be one of the tidiest frameworks on the market) is that we
do not use <style> tag for enclosing styles, since
@rule
prefix facilitates intermixability with
JavaScript (and most other applicable programming languages),
and usage of inheritance. Besides that, in contrast to Riot.js (as of version 3.4.2) it is possible to use expressions
in styles and to make the element stylable by external stylesheets (by declaring parameters annotated by @option
and using them accordingly).
By inheriting from LayoutTag
or FormattingObject
we would
declare our tag is not intended to be used in top level HTML
document, but only on visual medias. By inheriting from
VisualElement
we declare that our element has genuine semantical
meaning, yet only on visual medias (like images, banners, etc.), on all the
other medias alt. text can be used instead, our definition
forwards the (optional) content of the element as alt. text,
i.e. if the user considers alternative text desirable, they
can use <Timer>
alt. text</Timer>
instead of <Timer/>
.
Stylesheets as <!DOCTYPE> Extensions
Since our reworked stylesheets define new elements (and also defines their attributes,
specifies their type and optionally their default value or that they are required), it
should be considered a part of the DTD, so we propose the following type declaration
for HTML(reworked) documents utilizing reworked stylesheets:
<!DOCTYPE html @with /path/to/stylesheet>
or, for embedded css:
<!DOCTYPE html @with [
@import ./common.css screen, projection;
@import ./landscape.css screen and (orientation:landscape);
... // embedded stylesheet
]>