24.06.09

border-radius спешит на помощь

В соавторстве с Вадимом Макишвили

Для реализации скругленных уголков мы искали максимально легкое решение — отсутствие дополнительной разметки, минимум CSS и JS. Конечно, есть очень мощные средства, например, rocon, но нам они показались избыточными и громоздкими.

Идея была в том, чтобы использовать CSS-свойство border-radius, которое поддерживают некоторые прогрессивные браузеры:

  • Firefox начиная с версии 1.0 (~24% пользователей)
  • Safari начиная с 3.0 + Chrome (~2%)
  • Konquerer (~0,05%)

Итого, для ~25% пользователей уголки можно рисовать средствами браузера — уже неплохо.

Смешно, но свойство border-radius, которое есть в CSS3, пока не поддерживается ни одним браузером. Однако, некоторые браузеры поддерживают аналогичные проприетарные свойства, например, -moz-border-radius в Firefox.

.corners {
    /* Возможно какой-нибудь браузер в будущем, будем надеяться IE */
    border-radius: 4px;
    /* WebKit (Safari/Chrome) */
    -webkit-border-radius: 4px;
    /* KHTML (Konquerer) */
    -khtml-border-radius: 4px;
    /* Возможно Opera в будущем */
    -opera-border-radius: 4px;
    /* Gecko (Firefox) */
    -moz-border-radius: 4px;
}

Для остальных браузеров, не поддерживающих border-radius, будем яваскриптом вставлять доп. элементы для реализации уголков.


// Проверяет, поддерживает ли элемент elem CSS-свойство border-radius.
var isBorderRadiusSupported = function (elem) {
    var s = elem.style;
    return typeof s.borderRadius === "string" ||
           typeof s.WebkitBorderRadius === "string" ||
           typeof s.KhtmlBorderRadius === "string" ||
           typeof s.OperaBorderRadius === "string" ||
           typeof s.MozBorderRadius === "string";
};

// Добавляет внутрь элемента elem доп. элементы реализующие уголки.
var wrapInCorners = function (elem) {
    // Реализуем уголки любым известным способом
    $(elem).prepend('<i class="lt"></i><i class="rt"></i><i class="lb"></i><i class="rb"></i>');
};

// Реализует закругленные уголки с помощью доп. элементов
// для браузеров не поддерживающих CSS-свойство border-radius.
var checkCorners = function () {
    // Ищем все элементы с классом corners
    $('.corners').each(function () {
        // Если для данного элемента браузер не поддерживает border-radius
        if (!isBorderRadiusSupported(this)) {
            // Добавляем внутрь элемента доп. элементы реализующие уголки
            wrapInCorners(this);
        }
    });
};

// DOM загрузился и готов к обходу и манипуляциям
$(function () {
    checkCorners();
});

Плюсы решения:

  • HTML льется чистый, без доп. элементов, и, соответственно, лишняя разметка не мозолит глаз ни в статической верстке, ни в XSL-шаблонах.
  • В прогрессивных браузерах (примерно у четверти пользователей) уголки рисуются средствами браузера (максимально быстро).
  • Есть задел на будущее — если IE или Opera надумают реализовать border-radius, то наше решение готово к этому радостному событию.

16.06.09

Не хватает слов? Нарисуй письмо!

Выкатили сегодня пакет обновлений Яндекс.Почты. В нем есть киллер-фича — рисовалка! Не отходя от кассы формы нового письма, теперь можно нарисовать картинку и приложить ее к письму.

Подробности в блоге новой Яндекс.Почты.

P.S. Кстати, по-украински «Рисовалка» будет «Малювалка» :) Можете включить украинский язык интерфейса и проверить :)

11.06.09

Комментарии

/**
 * По-хорошему, объем комментариев должен быть не меньше
 * объема самого кода или даже больше. Я вообще стараюсь
 * сначала комментарий написать, а потом уже кусок кода.
 * Если русским языком не можешь сформулировать, что хочешь
 * чтобы код делал, значит рано еще сам код писать. Скажу
 * больше, акт написания комментария заставляет мозг
 * напрячься и обрести ясность мысли, что способствует
 * написанию стройного и четкого кода. Вы не замечали
 * за собой такого?
 */

03.06.09

Сайт «Музея советских игровых автоматов»

http://www.artlebedev.ru/everything/15kop/

Уже три с половиной месяца не работаю в Студии, а проекты с моим участием продолжают выходить :)

В детстве больше всего мне нравился автомат «Магистраль». Помню, когда мы жили в Витебске, постоянно бегал на вокзал и спускал в этот автомат все карманные деньги. Сначала я всегда выбирал учебный режим, зарабатывал на нем призовую игру, и уже призовую игру ехал на сложном режиме :)

В процессе работы над сайтом особый кайф я получил от создания страницы «Ночной рейс». Мега-крутая фишка получилась!

28.05.09

Новая Яндекс.Почта

Та-дам! Дорогие друзья, свершилось знаменательное событие! Команда Яндекс.Почты запустила новый интерфейс (Нео). Всем срочно бежать смотреть и тестировать.

Обо всех проблемах сообщайте нам через форму обратной связи, а также не забудьте отправить нам бочку меда или ложку дегтя. Спасибо :)

Поздравляю вас/нас с этим волнующим событием! Ура!

22.05.09

Будущее яваскрипта: ECMAScript 5

Очень впечатлился выступлением товарищей из ECMAScript о грядущих изменениях в языке. Рекомендую посмотреть всем яваскриптерам.

Слайды презентации

20.05.09

Гигапедия

Открыл для себя Гигапедию — сайт, где можно найти любую книгу в электронном виде и бесплатно ее скачать. Есть всё — техническая литература, художественная, аудиокниги, даже ноты. Это просто счастье какое-то! Нужно зарегистрироваться, тогда у вас появится поиск по Гигапедии.

Накачал новых книг по яваскрипту (Стефанова, Закаса), Набокова на английском, нот для бас-гитары. Где бы теперь еще время взять, чтобы всем этим насладиться? :)

15.05.09

Трабл с попапом с закругленными уголками поверх селекта в IE6

Уважаемые читатели, помогите кто чем может. (Сами мы не местные.)

Как известно, в IE6 селекты (однострочные и многострочные) всегда поверх любых других элементов на странице. Чтобы это побороть, нужно в вытаскиваемый наверх попап положить iframe, который в IE6 как бы «убивает» под собой селект.

Однако, если у попапа есть закругленные уголки и фон страницы отличный от белого, то возникает проблема. Если закругленный уголок попапа находится над селектом, то там просвечивает цвет фона страницы, а не белый от селекта.

Выглядит это так:

Что происходит:

  • iframe полностью прозрачный {filter: alpha(opacity=0);}
  • он «убивает» под собой селект
  • и начинает просвечивать бекграунд (черный)

Тестовая страница (ZIP)

Кто найдет решение, тому респект и уважуха :)

UPD: в каментах есть решение.

12.05.09

Gmail: Двоеточие в id-шнике

Продолжение статьи «Особенности верстки Gmail».

Мой коллега Иван Широков заметил, что все id-шники в верстке Gmail начинаются с двоеточия.

Хочу поделиться с вами своими соображениями, зачем это может быть сделано.

Во-первых, чтобы нельзя было (даже по ошибке) навесить стили для такого id-шника, потому что #:my {color: red;} не работает. Своеобразная защита, которая как бы подчеркивает, что id-шник используется только в яваскрипте.

Во-вторых, и в главных, чтобы элемент не был доступен по идентификатору в глобальной области видимости (global namespace). Когда мы пишем <div id="my">test</div>, этот дивчик становится доступен через идентификатор my в глобальной области видимости. То есть alert(my.tagName) выдаст «DIV» (сюрприз, сюрприз!). А если писать с двоеточием <div id=":my">test</div>, то уже хренушки — нет такого идентификатора в глобальной области видимости. При этом элемент по-прежнему можно достать через document.getElementById(':my'). На самом деле это очень круто, так как уменьшается вероятность коллизии в глобальной области видимости.

Все это лишь мои догадки. А вы что думаете?

08.04.09

Дилемма о загрузке JS-файлов

С одной стороны, конечно, хочется накладывать JS сразу по мере загрузки HTML. Иными словами, хорошо бы делать инициализацию JS-кода компонента сразу после загрузки HTML-кода компонента:

<div id="something">
    ...
</div>
<script>
    Something.init();
</script>

Понятно зачем — чтобы свести к минимуму задержку между двумя событиями: 1) HTML компонента отобразился и 2) JS компонента загрузился и инициализировался.

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

Разумеется, для этого нужно грузить JS-код компонента вперед HTML-кода (обычно это делают в <head>).

***

С другой стороны, следуя рекомендациям ведущих специалистов по борьбе с тормознутостью сайтов, хочется вынести загрузку всех JS-файлов в конец страницы (перед закрывающим тегом <body>).

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

Однако, минус очевиден — увеличивается задержка между рассмотренными выше событиями 1) и 2). То есть мы получаем, что пользователь дольше видит HTML с еще не наложенным яваскриптом.

***

Что делать? Я думаю, что правильный путь — это все-таки вынести загрузку всех JS-файлов в конец страницы, при этом в <head> грузить один маленький легковесный скрипт, который при попытке пользователя взаимодействовать с компонентом при еще не наложенном JS, будет сигнализировать ему, что, мол, все окей, подожди чуть-чуть, JS грузится и скоро наступит счастье.

Вот и Мэтт Снайдер похожим путем идет. А как вы решаете эту дилемму?