Markdown блог

Как Octopress, только на BEViS :)

Стилизация ребенка ссылки при :hover

Темы: IEСSS
Thursday, June 18, 2009

Хочу описать решение с пылу с жару.

Есть структура:

<a class="b-link" href="" >
    Телефон в копилке
    <img class="b-img" src="image.png" alt=""/>
</a>

Есть стили к ней:

.b-img {
    display: none
}

.b-link:hover .b-img {
    display: inline
}

Известно, что второй селектор в ИЕ6 не отработает.

Как мы с этим боролись?

На ссылку вешали одноразовый expression и расширяли селектор:

* html .b-link {
    zoom: expression(
        runtimeStyle.zoom = 1,
        onmouseover = function() {
            className += ' b-link-hover'
        },
        onmouseout = function() {
            className = className.replace(' b-link-hover', '')
        }
    );
}

.b-link-hover .b-img,
.b-link:hover .b-img {
    display: inline
}

Это было старое решение.

Элегантное решение

Новое решение рождено сегодня — оно очень дешевое — нужно написать один дополнительный селектор, который решает нам проблему.

.b-link:hover{
    word-spacing: 0
}

Суть проста - этот селектор перезапускает Reflow, после чего ИЕ6 начинает применять селекторы для элементов в ссылках .b-link:hover .b-img {} Приятно, что это решение работает несмотря на то, включен ли у ссылки hasLayout или нет. И не пугайтесь, это не обнуление пространства между словами, а дефолтное значение браузера.

Слова благодарности

Спасибо Роме Комарову за статью, к которой я сегодня очередной раз вернулся. Благодаря этой статье я понял, что можно не писать expression, если написать что-то из нижеследующего

.b-link:hover{background: #rgb}
.b-link:hover{background: url(transparent.gif)}
.b-link:hover{background: url(about:blank)}

Эксперимент показал, что свойство background-image не заставляет ИЕ6 перерисовать DOM. Этот селектор проблему не решает

.b-link:hover{background-image: url(about:blank)}

Но моя проблема была в том, что у элемента .b-link уже был фоновый цвет и сбрасывать его селекторами Ромы мне нельзя, потому что "дизайн".

.b-link{background: #feb247}

Первое, что пришло в голову - продублировать фоновый цвет. Оказалось, что ИЕ написан хорошо :) Он не перезапускает reflow, так как значение #rrggbb не изменилось:

.b-link{background: #feb247}
.b-link:hover{background: #feb247}

Второе, что мне пришло в голову — изменить последний символ в #rrggbb на "один вниз" — было 7, стало 6. И, да, заработало. При этом мой глаз не смог различить подмену цвета:

.b-link{background: #feb247}
.b-link:hover{background: #feb246}

Я позвал верстальщиков нашей Службы HTML-верстки и поделился тем, что решение Ромы рабочее и что у него есть такой нюанс с изменением rgb.

Виталя неделю назад обнаружил, что если просто экспрешином добавлять или удалять класс у ссылки (и больше ничего не делать), то нужный селектор тоже отрабатывает, потому что перезапускается reflow. Возможно есть еще какое-то свойство, которое сделает это и при этом не повлияет на часто используемые свойства. Надо поискать. Виталя, спасибо тебе за мысль :)

Я поискал 5 минут и был найден word-spacing. Итого, стили выглядят так:

.b-img {
    display: none
}

.b-link:hover {
    word-spacing: 0
}

.b-link:hover .b-img {
    display: inline
}

Пользуйтесь на здоровье :)