Препроцессинг CSS на клиенте
Представьте, что вы пишете блогохостинг и хотите позволить авторам блогов менять свой дизайн. Картиночки там вставлять, цвета менять, пропорции регулировать… Представили? Если хорошо представили, то уже поняли, что без констант и формул в CSS тут не обойтись.
При блуждании по блогам не хотелось бы грузить все стили заново, что неизбежно при серверном вычислении значений, а хотелось бы грузить лишь минимальную разницу — так называемый скин.
Итого, нам нужно грузить в дополнение к данным страницы: скин с константами и стили с формулами. Только две клиентские технологии позволяют сделать это: JS и XSLT. Однако первую очень любят отключать, а вторую отключать просто нет смысла. Поэтому вынесем CSS в XSLT контейнер, а заодно и не забудем про технологию XHTML-инклудов.
Напишем XHTML-ку и подключим к ней скин:
Напишем скин и подключим к нему стили:
И последний штрих — вычислим дополнительные константы, подставим их в стили и специальным шаблоном впрыснем их в результирующий XHTML:
Как видно мы по прежнему можем использовать возможности XHTML2 для вставки сторонних документов, а также применять довольно гламурный синтаксис для вставки в CSS констант, формул и примесей.
Совместимость: все попурярные настольные браузеры и часть продвинутых мобильных.
При блуждании по блогам не хотелось бы грузить все стили заново, что неизбежно при серверном вычислении значений, а хотелось бы грузить лишь минимальную разницу — так называемый скин.
Итого, нам нужно грузить в дополнение к данным страницы: скин с константами и стили с формулами. Только две клиентские технологии позволяют сделать это: JS и XSLT. Однако первую очень любят отключать, а вторую отключать просто нет смысла. Поэтому вынесем CSS в XSLT контейнер, а заодно и не забудем про технологию XHTML-инклудов.
Напишем XHTML-ку и подключим к ней скин:
<!DOCTYPE html>
<?xml-stylesheet type="text/xsl" href="skin.xsl?user:tenshi/rev:123"?>
<html>
<head>
<title>Демонстрация препроцессинга CSS с помощью XSL</title>
</head>
<body>
<h1>Заголовок раздела</h1>
<h2>Дополнительный текст описывающий этот раздел</h2>
<div src="index2.xml" srctype="text/xml">
<a href="index2.xml">Ссылка на подключаемый файл</a>
</div>
</body>
</html>Напишем скин и подключим к нему стили:
<t:stylesheet version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform">
<t:variable name="color.main" select=" '#eee' " />
<t:variable name="color.add" select=" '#369' " />
<t:variable name="size.border" select=" 16 " />
<t:variable name="size.decor" select=" 4 " />
<t:variable name="size.font" select=" 16 " />
<t:include href="styles.xsl?rev:123" />
</t:stylesheet>И последний штрих — вычислим дополнительные константы, подставим их в стили и специальным шаблоном впрыснем их в результирующий XHTML:
<t:stylesheet id="t:stylesheet" version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform">
<t:output method="html" doctype-public="-//W3C//DTD XHTML 2.0//EN"/>
<t:variable name="size.padding" select=" $size.border * 2 " />
<t:variable name="size.font.header" select=" $size.font * 2 " />
<t:variable name="mixin.header">
margin: 0;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
line-height: 1em;
</t:variable>
<t:template match=" head " mode="content">
<t:apply-templates select=" * " />
<style>/*<link type="text/css" rel="stylesheet" href="data:text/css,*/{{}}
html {{
background: {$color.main};
margin: 0;
padding: {$size.padding}pt;
}}
h1 {{
{$mixin.header}
border: {$size.border}pt solid {$color.add};
padding: {$size.padding}pt;
font-size: {$size.font.header}pt;
color: {$color.add};
}}
h2 {{
{$mixin.header}
font-size: {$size.font}pt;
font-style: italic;
color: {$color.main};
background: {$color.add};
padding: 0 {$size.border}pt {$size.border+$size.decor}pt;
}}
p {{
border-top: {$size.decor}pt dashed {$color.main};
font-size: {$size.font}pt;
color: {$color.main};
background: {$color.add};
margin: -{$size.decor}pt 0 0;
padding: {$size.padding}pt;
text-overflow: ellipsis;
overflow: hidden;
}}
/*"/>*/</style>
<script>
if( /webkit/i.test( navigator.userAgent ) ) new function(){
var styles= document.getElementsByTagName( 'style' )
var style= styles[ styles.length - 1 ]
style.innerText= unescape( style.innerText )
}
</script>
</t:template>
<t:template match=" @* | node() ">
<t:copy>
<t:apply-templates select=" @* " />
<t:apply-templates select=" . " mode="content" />
</t:copy>
</t:template>
<t:template match=" processing-instruction() " />
<t:template match=" node() " mode="content">
<t:apply-templates select=' node() ' />
</t:template>
<t:template match=" *[ @src and contains( @srctype, 'xml' ) ] " mode="content">
<t:apply-templates select=' document( @src )//body/node() ' />
</t:template>
</t:stylesheet>Как видно мы по прежнему можем использовать возможности XHTML2 для вставки сторонних документов, а также применять довольно гламурный синтаксис для вставки в CSS констант, формул и примесей.
Совместимость: все попурярные настольные браузеры и часть продвинутых мобильных.



комментарии (57)