истематизация экспрешнов
- Исправление полупрозрачных png пример
- Минимальные/максимальные ширины/высоты пример
- Позиционирование
- Перекрытие селектов айфреймом пример
- Растягивание высоты
- Opacity
- Размер шрифта в зависимости от dpi
- Реализация простого счётчика пример
- Эмуляция псевдоклассов (
:hover
,:focus
,:target
) пример - Благодарности
Небольшой disclaimer: используйте напильник, пожалуйста, — практически всегда в экспрешнах надо что-либо допилить!
справление полупрозрачных png
Тупо фильтр
* HTML .png-crop {
background-image:none;
zoom:1;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="ololo.png", sizingMethod="crop");
}
Исправление png с методом crop (лёгким движением руки меняется на «scale»)
* HTML .png-crop {
filter:expression(
function(t){
t.runtimeStyle.zoom = 1;
t.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src='+t.currentStyle.backgroundImage.split('\"')[1]+', sizingMethod=crop)';
t.runtimeStyle.backgroundImage = 'none';
}(this)
);
}
Исправление png для <img />
, не нужен прозрачный гиф. пример.
* HTML IMG {
_visibility:expression(
function(t){
t.runtimeStyle.visibility = 'hidden';
var png = document.createElement('png');
png.style.cssText = 'zoom:1;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + t.src + ',sizingMethod=scale);';
png.appendChild(t.replaceNode(png));
if (png.parentNode.getAttribute('href')) {
var pngclick = document.createElement('pngclick');
pngclick.style.cssText = 'position:absolute;overflow:hidden;width:expression(runtimeStyle.width = parentNode.offsetWidth);height:expression(runtimeStyle.height = parentNode.offsetHeight);';
t.parentNode.insertBefore(pngclick,t);
}
}(this)
);
}
инимальные/максимальные ширины/высоты
Только max-width, берётся из элемента, только пиксели (возможно, стоит добавить проверку на изменение ширины самого элемента). пример.
.maxwidth {
zoom:1;
maxwidth:expression(
function(t){
var w = t.parentNode.scrollWidth;
if (w != t.w) {
t.w = w;
var max = parseInt(t.currentStyle['max-width'], 10);
t.style.width = 'auto';
if (t.scrollWidth > max) {
t.style.width = max;
}
}
}(this)
);
}
min-width для BODY, берётся из свойства, только пиксели (standards-mode only (пока)) (+надо добавить кешируемость значения — чтобы перезаписывать его только если меняется).
* HTML BODY
{
zoom:expression(
function(t){
t.runtimeStyle.zoom = 1;
var max = parseInt(t.currentStyle['min-width'], 10);
var f = function() {
var w = document.documentElement.clientWidth;
if (w != t.w) {
t.w = w;
if (w < max) {
t.style.width = max;
} else {
t.style.width = 'auto';
}
}
};
f();
window.attachEvent('onresize',f);
}(this)
);
}
Max-width/max-height, только пиксели, одноразовый.
IMG {
zoom:expression(
function(t){
t.runtimeStyle.zoom = 1;
var maxW = parseInt(t.currentStyle['max-width'], 10);
var maxH = parseInt(t.currentStyle['max-height'], 10);
if (t.scrollWidth > maxW && t.scrollWidth >= t.scrollHeight) {
t.style.width = maxW;
} else if (t.scrollHeight > maxH) {
t.style.height = maxH;
}
}(this)
);
}
озиционирование
Реализация правильного абсолютного позиционирования (left+right/top+bottom), готово для «px» и «%», надо тестировать и поставить проверку на высоту/ширину (если можно). Может, добавить исправление для right/bottom при отстутствии left/top?
* HTML .tblr {
tblr:expression(
function (t) {
function to_px(input, dim) {
return input.match('%') ? Math.floor(dim / 100 * parseInt(input, 10)) : parseInt(input, 10);
}
var h = t.parentNode.offsetHeight || t.parentNode.parentNode.offsetHeight;
var w = t.parentNode.offsetWidth || t.parentNode.parentNode.offsetWidth;
var top = to_px(t.currentStyle.top, h);
var bottom = to_px(t.currentStyle.bottom, h);
var left = to_px(t.currentStyle.left, w);
var right = to_px(t.currentStyle.right, w);
if (t.h != h || t.top != top || t.bottom != bottom || t.w != w || t.left != left || t.right != right) {
if (h >= 0 && top >= 0 && bottom >= 0) {
t.h = h;
t.top = top;
t.bottom = bottom;
t.style.height = h - (top + bottom) > 0 ? h - (top + bottom) : 0;
}
if (w >= 0 && left >= 0 && right >= 0) {
t.w = w;
t.left = left;
t.right = right;
t.style.width = w - (left + right) > 0 ? w - (left + right) : 0;
}
}
}(this)
);
}
Фикс для убирания тряски в ие при фиксированном позиционировании
* HTML {
background-image:url(about:blank);
background-attachment:fixed;
}
Экспрешн для нейтрализации тряски в ие при фиксированном позиционировании
* HTML {
_behavior:expression(
function(t){
t.runtimeStyle.behavior = 'none';
var style;
if (t.currentStyle.backgroundImage) {
style = t.runtimeStyle;
} else {
var body = document.documentElement || document.body;
if (body.parentNode.currentStyle.backgroundImage) {
style = body.parentNode.runtimeStyle;
}
}
if (style) {
style.backgroundImage = 'url(about:blank)';
style.backgroundAttachment = 'fixed';
}
}(this)
);
}
пример
ерекрытие селектов айфреймомИсправление элементов над селектами, надо бы сделать вариант с отслеживанием состояния исходного элемента (кешируемый экспрешн на дисплей?)
.iframed {
zoom:expression(
function(t){
t.runtimeStyle.zoom = 1;
t.insertAdjacentHTML('beforeBegin','<iframe src="about:blank" style="position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;padding:0;margin:0;border:0;expression:expression(function(t){var L=t.nextSibling.offsetLeft;var T=t.nextSibling.offsetTop;var W=t.nextSibling.offsetWidth;var H=t.nextSibling.offsetHeight;if(t.L!=L||t.T!=T||t.W!=W||t.H!=H){ t.runtimeStyle.left=t.L=L;t.runtimeStyle.top=t.T=T;t.runtimeStyle.width=t.W=W;t.runtimeStyle.height=t.H=H;}}(this));"></iframe>')
}(this)
);
}
астягивание высоты
Высота: 100%
.height100 {
position:absolute;
stretch:expression(
function(t){
var h = t.parentNode.offsetHeight;
if (t.h != h) {
t.style.height = t.h = h;
}
}(this)
);
}
pacity!
Увы, восьмой ие должен работать в режиме седьмого.
.opacity {
filter:expression(
function(t){
t.runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + t.currentStyle.opacity * 100 + ')';
}(this)
);
}
А если надо без экспрешнов и в восьмом, надо тупо вот так:
.opacity {
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity:0;
}
азмер шрифта в зависимости от dpi
Применяем для BODY, переопределяя стандартную величину (на самом деле, надо бы брать и парсить эту величину, а не хардкодить, по-хорошему-то)
BODY {
font-size:expression(
function(t){
if (screen.deviceXDPI == screen.logicalXDPI) {
t.runtimeStyle.fontSize = 6000/screen.logicalYDPI + '%';
} else {
t.runtimeStyle.fontSize = '62.5%';
}
}(this)
);
}
пример
еализация простого счётчикаВсем браузерам отдаём:
.list {
counter-reset:list_item;
}
.list-item {
display:block;
}
.list-item:before,
.list-item-before {
content:counter(list_item);
counter-increment:list_item;
}
А только для ие:
.list-item {
list-style-type:expression(
function(t){
t.runtimeStyle.listStyleType = 'none';
t.insertAdjacentHTML('afterBegin','<span class="list-item-before">' + (++t.parentNode.IEcounter || (t.parentNode.IEcounter = 1)) + '</span>');
}(this)
);
}
пример
муляции псевдоклассовЭмуляция :hover
* HTML .some-block {
_behavior: expression(
function(t, hoverClass){
t.runtimeStyle.behavior = 'none';
hoverClass = hoverClass || t.className ? t.className.replace(/([^\s]+)/g,'$1_hover') : 'hover';
t.attachEvent('onmouseover',function() {
t.className += (' ' + hoverClass);
});
t.attachEvent('onmouseout',function() {
t.className = t.className.replace(new RegExp(' ' + hoverClass,'g'), '');
});
}(this)
);
}
Эмуляция :focus
* HTML .type-text {
_behavior: expression(
function(t, focusClass){
t.runtimeStyle.behavior = 'none';
focusClass = focusClass || t.className ? t.className.replace(/([^\s]+)/g,'$1_focus') : 'focus';
t.attachEvent('onfocus',function() {
t.className += (' ' + focusClass);
});
t.attachEvent('onblur',function() {
t.className = t.className.replace(new RegExp(' ' + focusClass,'g'), '');
});
}(this)
);
}
Эмуляция :target
#SomeBlock {
behavior: expression(
function(t, targetClass){
if (t.id) {
var hash = window.location.hash;
if (!t.targetClass) {
t.targetClass = targetClass || t.className ? t.className.replace(/([^\s]+)/g,'$1_target') : 'target';
}
if (t.lastHash != hash) {
t.lastHash = hash;
if ("#"+t.id == hash) {
t.className += (' ' + t.targetClass);
} else {
t.className = t.className.replace(new RegExp(' ' + t.targetClass,'g'), '');
}
}
} else {
t.runtimeStyle.behavior = 'none';
}
}(this)
);
}
лагодарности
- Павлу Корнилову за одноразовые экспрешны
- Виталию Харисову за кешируемые экспрешны (примерно 40-й слайд)
- Stu Nicholls за идею с селектами
- Игорю Зеничу за раскрытие темы dpi