📜 ⬆️ ⬇️

CSS preprocessing on client

Imagine that you are writing a blog hosting and want to allow blog authors to change their design. Picture there to insert, change colors, adjust the proportions ... Presented? If you have a good idea, you already understand that you cannot do without constants and formulas in CSS.

When wandering around blogs, I wouldn’t want to reload all styles, which is inevitable when server-side calculating values, but I would like to load only the minimal difference - the so-called skin.

Total, we need to load in addition to the page data: a skin with constants and styles with formulas. Only two client technologies allow you to do this: JS and XSLT. However, the first one is very fond of turning off, and the second just does not make sense to turn off. Therefore, we will place the CSS in the XSLT container, and at the same time we will not forget about the XHTML technology.
')
Let's write XHTML-ku and connect the skin to it:
<! DOCTYPE html > <br> <? xml-stylesheet type ="text/xsl" href ="skin.xsl?user:tenshi/rev:123" ? > <br> < html > <br> < head > <br> < title > CSS XSL </ title > <br> </ head > <br> < body > <br> < h1 > </ h1 > <br> < h2 > </ h2 > <br> < div src ="index2.xml" srctype ="text/xml" > <br> < a href ="index2.xml" > </ a > <br> </ div > <br> </ body > <br> </ html >

Write the skin and connect the styles to it:
< t:stylesheet version ="1.0" xmlns:t ="http://www.w3.org/1999/XSL/Transform" > <br><br> < t:variable name ="color.main" select =" '#eee' " /> <br> < t:variable name ="color.add" select =" '#369' " /> <br><br> < t:variable name ="size.border" select =" 16 " /> <br> < t:variable name ="size.decor" select =" 4 " /> <br> < t:variable name ="size.font" select =" 16 " /> <br><br> < t:include href ="styles.xsl?rev:123" /> <br><br> </ t:stylesheet >

And the final touch - let's calculate additional constants, substitute them into styles and use a special template to inject them into the resulting XHTML:
< t:stylesheet id ="t:stylesheet" version ="1.0" xmlns:t ="http://www.w3.org/1999/XSL/Transform" > <br><br> < t:output method ="html" doctype-public ="-//W3C//DTD XHTML 2.0//EN" /> <br><br> < t:variable name ="size.padding" select =" $size.border * 2 " /> <br> < t:variable name ="size.font.header" select =" $size.font * 2 " /> <br><br> < t:variable name ="mixin.header" > <br> margin: 0;<br> text-align: center;<br> text-overflow: ellipsis;<br> overflow: hidden;<br> line-height: 1em;<br> </ t:variable > <br><br> < t:template match =" head " mode ="content" > <br> < t:apply-templates select =" * " /> <br> < style > /* < link type ="text/css" rel ="stylesheet" href ="data:text/css,*/{{}}<br><br>html {{<br> background: {$color.main};<br> margin: 0;<br> padding: {$size.padding}pt;<br>}}<br><br>h1 {{<br> {$mixin.header}<br> border: {$size.border}pt solid {$color.add};<br> padding: {$size.padding}pt;<br> font-size: {$size.font.header}pt;<br> color: {$color.add};<br>}}<br><br>h2 {{<br> {$mixin.header}<br> font-size: {$size.font}pt;<br> font-style: italic;<br> color: {$color.main};<br> background: {$color.add};<br> padding: 0 {$size.border}pt {$size.border+$size.decor}pt;<br>}}<br><br>p {{<br> border-top: {$size.decor}pt dashed {$color.main};<br> font-size: {$size.font}pt;<br> color: {$color.main};<br> background: {$color.add};<br> margin: -{$size.decor}pt 0 0;<br> padding: {$size.padding}pt;<br> text-overflow: ellipsis;<br> overflow: hidden;<br>}}<br><br> /*" /> */ </ style > <br> < script > <br> if ( /webkit/i.test( navigator.userAgent ) ) new function (){<br> var styles= document .getElementsByTagName( 'style' )<br> var style= styles[ styles.length - 1 ]<br> style.innerText= unescape( style.innerText )<br> }<br> </ script > <br> </ t:template > <br><br> < t:template match =" @* | node() " > <br> < t:copy > <br> < t:apply-templates select =" @* " /> <br> < t:apply-templates select =" . " mode ="content" /> <br> </ t:copy > <br> </ t:template > <br> < t:template match =" processing-instruction() " /> <br><br> < t:template match =" node() " mode ="content" > <br> < t:apply-templates select =' node() ' /> <br> </ t:template > <br> < t:template match =" *[ @src and contains( @srctype, 'xml' ) ] " mode ="content" > <br> < t:apply-templates select =' document( @src )//body/node() ' /> <br> </ t:template > <br><br> </ t:stylesheet >

As you can see, we can still use the features of XHTML2 to insert third-party documents, as well as use a rather glamorous syntax to insert constants, formulas and impurities into CSS.

Compatibility: all popular desktop browsers and some advanced mobile.

Source: https://habr.com/ru/post/93118/


All Articles