Систематизация экспрешнов

Неболь­шой dis­claimer: ис­поль­зуй­те на­пиль­ник, по­жа­луй­ста, —прак­ти­че­ски все­гда в экс­преш­нах надо что-либо до­пилить!

Исправление полупрозрачных 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, бе­рёт­ся из свой­ства, толь­ко пик­се­ли (stan­dards-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+bot­tom), го­то­во для «px» и «%», надо те­сти­ро­вать и по­ста­вить про­вер­ку на вы­со­ту/​​ши­ри­ну (если мож­но). Мо­жет, до­ба­вить ис­прав­ле­ние для right/​​bot­tom при от­стут­ствии 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)
    );
    }

Opacity!

Увы, вось­мой ие дол­жен ра­бо­тать в ре­жи­ме седь­мого.

.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)
    );
    }

Благодарности