Несколько полезных CSS трюков

Во время работы над последним проектом, накопилось несколько интересных CSS трюков, о которых хочу рассказать. Хотя, возможно, это уже придумано до нас и все об этом уже знают. В примерах используется LESS, а не чистый CSS.

Событие автоподстановки в инпут поля

Проблема: узнать, что пользователь воспользовался функцией автоподстановки. Задача была в том, чтобы подсвечивать кнопку Login, если в полях e-mail и password введено что-либо. Проблема в том, что если эти поля заполняются автоподстановкой из ключницы браузера, то событие change на инпутах не выстреливает.

Решение: использовать псевдокласс :valid. Он срабатывает у инпута, если в нем есть контент, который удовлетворяет типу инпута (text, e-mail) и если у этого инпута стоит атрибут required. Правда решение не работает в IE, но нам не требуется поддержка этого браузера.

<input required="required" type="email" />
<input required="required" type="password"/>
<div>Login</div>

.email-input:valid ~  .password-input:valid ~ .go {
    //стили для активной кнопки Login
}

:hover в мобильных устройствах

Проблема: отключить реакцию браузера на псевдокласс :hover в CSS, которые там имеются от десктопной версии. Поскольку они блокируют клики, непредсказуемы в своем поведении, остаются висеть до клика по другому элементу.

Решение: поскольку мы использует Modernizr и LESS, у нас из коробки есть классы touch и no-touch. Поэтому при описании ховеров просто пишем использовать ховер только для версий с мышой, а для версий с тачем использовать :active (если надо):

.element {

    //стили элемента

    .no-touch &:hover,
    .touch &:active {
        //стили элемента при наведении мыши или таче пальцем
    }
}

Прячем placeholder при получении фокуса инпутом

Проблема: стандартное поведение браузеров (не всех, но многих) предусматривает скрытие placeholder сразу, как только в поле введен хотя-бы один символ. Нам хотелось, чтобы placeholder скрывался сразу при заходе в инпут. И сделать это нужно было без использования JS.

Решение: использовать псевдокласс :placeholder вместе с псевдоклассом :focus чтобы делать цвет текста placeholder невидимым при получении фокуса. Работает опять же не во всех браузерах, но нам все и не нужны были.

input:focus::-webkit-input-placeholder,
input:focus:-moz-placeholder {
    color: transparent !important;
}

Некорректный рендер картинки при background-size:cover в webkit браузерах (и не только).

Проблема: картинка иногда не занимает весь контейнер, и остаются однопиксельные пропуски по краям контейнера.

Первое решение: если допустимо отрезать от картинки немного лишнего сверх того что отрезает cover, тогда используя :after или :before вставляем псевдоэлемент в контейнер, назначаем фоновую картинку ему, а размеры его делаем больше родителя на пару пикселей (http://jsfiddle.net/NVu3d/).

.element {
    position: relative;
    width: 200px;
    height: 100px;
    overflow: hidden;

    &:after {
        content:'';
        position: absolute;
        left: -2px;
        right: -2px;
        top: -2px;
        bottom: -2px;
        background-image: url(...);
        background-size: cover;
    }
}

Второе решение: если эта картинка используется в качестве фоновой и занимает всегда все окно, тогда можно динамически вставить media query, которое будет мониторить текущее соотношение сторон окна браузера с соотношением сторон картинки и соответственно проставлять background-size: auto 100% вместо дефолтного background-size: 100% auto; (http://jsfiddle.net/NRDA9/)

.element {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-image: url(...);
    background-size: 100% auto;
    background-position: 50% 50%;
}

@media screen and (max-aspect-ratio: IMAGE_WIDTH / IMAGE_HEIGHT) {
    .element {
         background-size: auto 100%;
    }
}

Лесенка вокруг элемента при применении к нему трехмерных трансформаций в FireFox

Проблема: при применении 3d трансформаций к панельке, которая сложным образом складывалась в пространстве, в FireFox по контуру элемента рендерилась ужасная «лесенка».

Решение: применить в элементу едва заметную тень.

.panel-body {
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05);
}

2fd84cbf6db49bc8eef82e3fd3b8fd65