Pull to refresh

Препроцессинг CSS на клиенте

Reading time 6 min
Views 2.1K
Представьте, что вы пишете блогохостинг и хотите позволить авторам блогов менять свой дизайн. Картиночки там вставлять, цвета менять, пропорции регулировать… Представили? Если хорошо представили, то уже поняли, что без констант и формул в CSS тут не обойтись.

При блуждании по блогам не хотелось бы грузить все стили заново, что неизбежно при серверном вычислении значений, а хотелось бы грузить лишь минимальную разницу — так называемый скин.

Итого, нам нужно грузить в дополнение к данным страницы: скин с константами и стили с формулами. Только две клиентские технологии позволяют сделать это: JS и XSLT. Однако первую очень любят отключать, а вторую отключать просто нет смысла. Поэтому вынесем CSS в XSLT контейнер, а заодно и не забудем про технологию XHTML-инклудов.

Напишем XHTML-ку и подключим к ней скин:
<!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>

Напишем скин и подключим к нему стили:
<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>

И последний штрих — вычислим дополнительные константы, подставим их в стили и специальным шаблоном впрыснем их в результирующий 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>

Как видно мы по прежнему можем использовать возможности XHTML2 для вставки сторонних документов, а также применять довольно гламурный синтаксис для вставки в CSS констант, формул и примесей.

Совместимость: все попурярные настольные браузеры и часть продвинутых мобильных.
Tags:
Hubs:
+31
Comments 57
Comments Comments 57

Articles