Создание реалистичной кнопки средствами CSS3

Автор оригинала: Anomaly Innovations
  • Перевод
image

Цель — создание кнопки, как на изображении, не единой картинкой, а с помощью CSS3



Я хочу последовательно рассказать о процессе создания кнопки и эффектах.

Вся соль — в деталях


Смысл в том, чтобы использовать комбинацию эффектов для создания трехмерного объекта. Майк Рандл рассказывает о тонкости в интерфейсах, я же надеюсь рассказать немного больше об этом. Идея состоит в следующем:
  • Кнопка лежит на поверхности
  • Кнопка немного приподнята и её текстура отличается от поверхности
  • Текст «вдавлен» в кнопку

HTML, используемый для кнопки немного чрезмерен, но смысл будет понятен, когда мы углубимся в детали
<a class="button"><b class="o"><b class="m"><b>Post</b></b></b></a>

* This source code was highlighted with Source Code Highlighter.


А сейчас разберемся со стилем:

image
  1. Простой градиент, более светлый наверху, показывает, что источник света сверху и поверхность кнопки немного приподнята. Используем фоновое изображение шириной в 1 пиксель.
    a.button b.m {
    background: transparent url(button.png) repeat-x 0 0;
    }

  2. Светлая граница по краям — отражения света. Мы используем свойство CSS3 rgba для этого. Используем альфа-смешивание, т.к. отражаемый свет гораздо лучше виден внизу.
  3. Жесткая 1px верхняя граница, чтобы показать, что свет от верхнего края свет отражается сильнее.
    a.button b.m {
    border-width: 1px;
    border-style: solid;
    border-color: #FFF rgba(255, 255, 255, 0.33) rgba(255, 255, 255, 0.33);
    }

  4. Более светлая 1px нижняя граница, чтобы создать эффект, что кнопка находится прямо в поверхности.
    a.button {
    border-width: 1px;
    border-style: solid;
    border-color: transparent transparent rgba(255, 255, 255, 0.63);
    }

  5. 1px граница вокруг кнопки, чтобы показать тень кнопки на поверхности. Снова используем rgba
    a.button b.o {
    border: 1px solid rgba(0, 0, 0, 0.56);
    }

  6. И наконец, тень для текста, чтобы создать эффект «вдавленности»
    a.button b.m b {
    text-shadow: 0 1px 0 #DDD;
    color: #262626;
    }


Разные состояния кнопок


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

image

Мне нравится, когда кнопка «нажата», но при этом никуда не сдвигается. Изменим форму кнопки от выпуклой к вогнутой

Рассмотрим это более подробно:

image
  1. Вертикально отразите градиент. Темная часть градиента темнее по сравнению с предыдущем состоянием, т.к. свет, падающий на на нижнюю часть выпуклой формы отражается сильнее, чем свет, падающий верхнюю часть вогнутой.
    a.button:active b.m {
    background-position: 0 -160px;
    }

  2. Светлая верхняя граница кнопки подчеркивает, что её края не двигаются
  3. Нижняя граница светлее, так как основная граница также не двигается
  4. Нижняя граница светлее, так как основная граница также не двигаются
  5. Боковые края чуть светлее (но не намного), так как они двигаются с поверхностью
    a.button:active b.m {
    border-color: rgba(255, 255, 255, 0.11) rgba(255, 255, 255, 0.23) rgba(255, 255, 255, 0.27);
    }



Ниже представлена большая часть css, а здесь, использваный спрайт.
a.button {
text-decoration: none;
border-color: transparent transparent #ECECEC; /** rgba fallback **/
border-color: transparent transparent rgba(255, 255, 255, 0.63);
cursor: pointer;
outline: none;
}
a.button:hover {
text-decoration: none;
}
a.button,
a.button b.o,
a.button b.m {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
border-width: 1px;
border-style: solid;
display: block;
}
a.button b.o {
border-color: #5A5A5A; /** rgba fallback **/
border-color: rgba(0, 0, 0, 0.56);
}
a.button b.m {
background: transparent url(button.png) repeat-x 0 0;
border-color: #FFF transparent #C7C7C7; /** rgba fallback **/
border-color: #FFF rgba(255, 255, 255, 0.33) rgba(255, 255, 255, 0.33);
}
a.button:hover b.m {
background-position: 0 -80px;
}
a.button:active b.m {
background-position: 0 -160px;
border-color: #B7B7B7 transparent #D4D4D4; /** rgba fallback **/
border-color: rgba(255, 255, 255, 0.11) rgba(255, 255, 255, 0.23) rgba(255, 255, 255, 0.27);
}
a.button b.m b {
display: block;
font-weight: bold;
padding: 4px 8px;
text-shadow: 0 1px 0 #DDD;
color: #262626;
/** Make the text unselectable **/
-moz-user-select: none;
-webkit-user-select: none;
}


Демо в оригинале статьи
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 97

    0
    Было бы хорошо еще ссылку, где можно взглянуть на это чудо в действии.
    +7
    Гулять — так гулять! Градиенты через CSS, вместо дополнительных элементов в разметке использовать псевдоклассы :before и :after (Не уверен, правда, что получится).
      –1
      не везде поддерживается
        +1
        Ну так и border-radius не всеми браузерами поддерживается (Взять ту же оперу версией меньше 10.5. Некоторые пользуются даже 9-ой серией. Про IE даже не говорю)
          0
          градиенты CSS поддерживаются во всех свежих браузерах, а в ИЕ через фильтры
            0
            Opera?
              0
              Вы правы, я несколько поторопился. Но для Opera можно использовать SVG тогда.
              0
              Фильтры вырубают сглаживание у текста. Из-за этого они практически бесполезны.
                0
                Не тестил, пасиб за инфу.
          +4
          вот это более впечатляет

          CSS Gradient Dropdown Menu
          Below is a pure CSS gradient dropdown menu using CSS3 text-shadow, radius-border, and box-shadow (no Javascript or image)
          www.webdesignerwall.com/demo/css3-dropdown-menu/css-gradient-dropdown.html
            0
            отличное демо возможностей CSS3
            раньше для повторения этого меню писали по 400 строчек JS… да и картинок штук 8 прикладывали к этому
              +14
              400 строчек JS для такого меню? Да вы с ума сошли!
                0
                да это ж не я его писал… видел своими глазами лет 8 назад
                теперь все проще, одна жирная возможность RGBA или градиента чего стоит
              +4
              А чего тут впечатляющего? Из css3 тут только оформительские штуки, всё остальное доступно с css2.1. При этом оно не работает в IE6 — тогда это точно не достижение, а просто тупое использование :hover на любой элемент.
              Поглядите на cssplay.co.uk — вот там действительно полёт инженерной мысли : D
                0
                с чего это оно должно работать в IE6?
                css3 в IE6?
                нуну

                p.s. кто-то еще тестирует сайты в IE6?
                  +1
                  Если внимательно прочитать то, что я написал, то можно увидеть для чего тут используется CSS3, остальное — CSS<=2.1

                  В IE6 сайты тестируют реалисты
                    0
                    Реалисты тестируют минимум в ИЕ7. В ИЕ6 отсталые реалисты тестируют
                      –2
                      Никого не хотел обидеть
                        +4
                          +1
                          А у нас продукт, идущий с жестким условием: все, кроме IE
                            +2
                            У всех разные ситуации, кто-то делает сервисы для людей, кто-то для гиков, а кто-то вообще для себя
                    • НЛО прилетело и опубликовало эту надпись здесь
                      –14
                      ололо IE6…
                      что впечатляющего? то что такое
                        +8
                        Comment decoding failed
                          –1
                          :)
                          …такое симпатичное apple-стайл меню можно реализовать без использования картинок и javascript К. О.
                            0
                            Без JS его можно реализовать с помощью CSS2.1
                            Без картинок его можно реализовать с помощью тривиальных CSS3 свойств
                            Впечатляет??? Меня нет
                              –1
                              ну наверно я слишком впечатлительный:) карму понижать необязательно было, спокойнее надо быть, товарищ
                                +1
                                Мне не нравятся ошибки декодирования комментариев
                                  –4
                                  это к разработчикам хабра, а не ко мне)
                      +3
                      css3 это конечно здорово, если бы его можно было использовать уже сейчас, а пока ситуация такова: habrahabr.ru/linker/go/88870/ это нереально ((
                        +1
                        Надо быть оптимистом, Chrome и Safari очень даже ничего так с поддержкой CSS3. Также неплохи в этом плане и FireFox с Opera. Я думаю, что если разработчики и некоторые крупные проекты все-таки начнут больше использовать CSS3, то ситуация с IE тут же изменится. Либо начнется еще больший отток пользователь от этого браузера. Google не спит, и если все «сочности» и «красивости» появятся на гугле и других ресурсах, конечный пользователь увидит весь сок и выяснит что ему поставить, чтобы у него было также ;)
                          0
                          С предложением быть оптимистом, я полностью согласен ;) А вот про пользователей… жаль, но многим главное, что бы «работало», при этом предложение обновить их браузер с ИЕ6 на более новый встречаются в штыки, я даже и не говорю про установку Opera, FireFox или Chrome ) Так же множество людей, на работе используют старое железо, старые ОС, и старые браузеры… годами не обновляющиеся, тут опять таки, лид бы «работало»… это все печально, но реально.
                            +2
                            Часто общаюсь с людьми, которые заказывали у нас сайт или нет, но так как основная сфера работы именно разработка сайтов и работа с клиентом, то замечал что люди довольно активно готовы перейти на новый, другой браузер, а некоторые очень даже лояльно относятся если я им объясняю что, например, скругленных уголков в IE6 не будет или еще какие тонкости.

                            Очень рады всяким мелким фишечкам и приблудам и чтобы быстрее работала переходят на адекватные браузеры
                              +2
                              Вам везет, я согласен, много клиентов, именно так относятся. Но есть и Те, коих не мало, которые на отсутствие «скругленных уголков в IE6» говорят: «так делайте что бы были». Вот и приходится делать без использования вкусностей, а по старинке с картинками и геморроем ;)
                                0
                                Бывает, исключение подтверждает правило ) самодуров достаточно, ага
                              0
                              Я все чаще использую в своей работе Graceful Degradation. Главное чтобы сайт выглядел достаточно прилично и в ИЕ6, не разваливался там на куски. 90% заказчиков этого достаточно. Ну а продвинутые пользователи увидят свои бонусы.
                                0
                                Новые браузеры показывают куда большую скорость отрисовки. Поэтому вы можете сказать — хотите, чтобы ваш комп быстрее работал, давайте покажу. И поставьте свежий браузер, да сделайте сравнение с ИЕ6.
                              –3
                              Особенно «впечатлил» IE8, прогресс с броузерами в Microsoft очевидно, замер, умер
                              +4
                              когда уже 1-пиксельные картинки вымрут?
                                0
                                Будем считать что это деталь…
                                +12
                                <a class=«button»><b class=«o»><b class=«m»><b>Post</b></b></b></a>

                                Дальше неинтересно.
                                  +10
                                  Ага, особенно если вспомнить, что ссылка <a> — это не кнопка (не элемент формы <button /> или <input type=«submit» />) и использовать ее для отправки данных не верно. Т.к. мы как минимум решаемся возможности средств встроенных в браузер для post/get, без использования JS.
                                    0
                                    И по Enter'у она не отработает (опять-таки без JS).
                                      +1
                                      Это решается через <noscript>/></noscript>
                                        +2
                                        парсер лох((
                                          +2
                                          Казалось бы, при чем тут
                                          Создание реалистичной кнопки средствами CSS3


                                          Я хочу нормальную кнопку, а не ссылку, требующую дополнительных усилий по ее внедрению в форму.
                                            +1
                                            Это похвально, но обычную кнопку стилизовать очень трудно, особенно, во всяких там IE — кромешный ад с паддингами там. Кто сталкивался, тот знает.
                                              0
                                              Понятное дело. Надеюсь, что увижу в этой жизни кроссбраузерные красивые кнопки ;)
                                                0
                                                Есть способ, собираюсь написать статейку, да все некогда :( Надеюсь, ближе к концу недели найду время
                                                  0
                                                  Только чур без использования какого-нибудь margin-left: -65535px; для сокрытия кнопки и подстановки своего элемента ;)
                                                    0
                                                    ужас какой, ну у вас и фантазия :)
                                              0
                                              А какая связь между кнопкой и формой? Автор обещал телепатическую отправку post запросов?
                                                +2
                                                Кнопка (button или input[type=submit]) изначально предназначена для отправки данных формы. Ссылка нужна для совершенно других целей.

                                                Не спорю, иногда очень красиво смотрятся большие ссылки в виде кнопок, но если я читаю «кнопка» — значит должен быть элемент «кнопка».

                                                Это мое мнение. Про саму реализацию я в первом комменте высказался.
                                                  –1
                                                  Да конечно, это логически правильно отправлять данные формы через input type=«submit», но смысл парится, если у нас на странице используется тонна JS для всяких там аяксов, при этом повесить отправку данных формы на красиво оформленную ссылку вообще не составит труда. Тем более если кнопка имеет класс button, что позволит легко найти её в коде.
                                                    +5
                                                    Мое мнение наверное покажется Вам архаичным, но я считаю, что JS должен использоваться только для улучшения работающей страницы. Т.е. все эти финтифлюшки типа отправки комментариев через Ajax, скругленных уголков и прочего, не должны быть во главе угла. Пользователь без JS должен иметь полностью работоспособный сервис.

                                                    Тут выше предлагали использовать NOscript, как вариант.
                                                      0
                                                      В чем то вы правы, но сейчас вокруг нас появляется все больше сервисов и приложений, которые, для своей работы в обязательном порядке требуют включенный js.

                                                      К тому же, реализовать например функционал приличного интернет магазина без использования js — это адова работа, нам приходилось такое делать.
                                                        +1
                                                        Конечно, есть отдельные исключения, не спорю (ту же админку обычно тупо на JS завязывают). Но отказываться от нативных элементов для красивостей — это слишком :)
                                                    0
                                                    То есть Вы как пользователь сайта, когда видите объёмную кнопку, сразу представляете себе как она будет отправлять post запросом на почту какого-нибудь hotbox данные заполненной формы? Как всех Internet Explorer успел изувечить…
                                        +13
                                        кнопка должна быть кнопкой (а не ссылкой)
                                          0
                                          В угол нажмите)
                                            –4
                                            А кнопка обязательно должна что-то куда-то отправлять? В наш век состоявшегося javascript.
                                              +1
                                              не понял вопрос
                                                0
                                                По вашему мнению и вы в нём не едины, как видно, кнопка обязательно должна быть input button? Зачем?
                                                Ведь кнопки уже не всегда на формах и далеко не всегда вызывают submit.
                                                Почему при желании кнопкой не сделать любой элемент?
                                                Я сторонник качественной вёрстки, но мне кажется вы слишком ограничиваете рамки.

                                                  +2
                                                  Я не люблю отвечать вопросом на вопрос, но разве кнопка должна делать только submit?
                                                  Для меня логично, что ссылка отвечает за переход на другой url, кнопка отвечает за события по нажатию. У этих компонентов абсолютно различная логика.
                                            +1
                                            Использую кнопки из jQuery UI и пока доволен.
                                              0
                                              В ExtJS всё тоже чудесно.
                                                0
                                                В какого рода проектах Вы используете jQuery UI? На мой взгляд он несколько тяжеловат.
                                                  0
                                                  Сайты для SMB. С весом особых проблем нет. Пользуюсь CDN.
                                                +2
                                                Вот еще есть демка: torqueo.net/files/pretty-buttons/buttons.html
                                                Правда, на спрайтах, зато работает везде. Хотя, конечно, побыстрее бы уже CSS3 на полную использовать!
                                                  –1
                                                  Это нормально, что после нажатия кнопа остается нажатой, пака не нажмешь другую? (Опера 10.52)
                                                    –2
                                                    Это косячок Оперы. Про Оперу кстати, делал недавно подобные кнопки, только там при наведении появлялась легкая тень вокруг, так вот, в опере тень при наведении — сплошной баг. Халтурно они там поддержку теней сделали.
                                                      0
                                                      Это косячок Оперы.
                                                      Да неужели? А так же фаерфокса? Или, может быть, автор страницы дурак, что повесил одинаковые стили на a.btn:hover и a.btn:focus?
                                                        0
                                                        Про пример согласен, там автор не досмотрел, но про остальное, у оперы реально косяк с тенями:

                                                        пример
                                                          +1
                                                          Ну уж не дурак — просто по-недосмотру) Я автор сих кнопок.
                                                            0
                                                            Кстати даже не по-недосмотру. Я вспомнил. Там нету отдельного состояния кнопки для :focus, поэтому, сделал так, как есть сейчас.
                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                      0
                                                      Визуальный результат мне нравится, а реализация — просто отстой. Такую же кнопку проще сделать одним спрайтом с одной картинкой, и кода будет меньше, и работать будет именно как кнопка, а не ссылка.
                                                        +1
                                                        а что тег button отменили? почему ссылку то использовать?
                                                          0
                                                          А зачем картинка? Есть же градиенты в Firefox и WebKit.
                                                            +1
                                                            Я градиенты и использовал и всего один лишний div в вёрстке.
                                                            +7
                                                            Всё тоже самое делается легко без экстра-разметки, достаточно использовать несколько box-shadow через запятую. Ну и элемент button был бы здесь уместнее.
                                                            0
                                                            Познавательно.
                                                              –2
                                                              Вот за это я и не люблю CSS!
                                                              Ради такой мелочи приходится писать тонну плохо понятных извращений :-(
                                                                0
                                                                Эта «тонна» совсем не тонна, когда вы понимаете, что она означает.
                                                                К тому же у нас может быть сотня кнопок на разных языках, а стиль у них один. И нет нужды вырисовывать кнопки для всех языков во всех состояниях.

                                                                с Ув. К.О.
                                                                0
                                                                  +5
                                                                  У одного меня в голове не вязется CSS 3 и тэг b?
                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                    0
                                                                    Мясо какое-то…
                                                                      0
                                                                      Проще использовать -border-image для этих целей.
                                                                      Такие элементы отжирают прилично, особенно на мобильных девайсах.
                                                                        0
                                                                        Хотелось бы в конце статьи видеть список браузеров, в которых это работает.
                                                                          0
                                                                          IE8 — нет углов и не «нажимается»
                                                                          Opera (10.51) — не «нажимается»
                                                                          FF3.6, Chrome 4 — всё ок.
                                                                          Днём допишу более старые версии IE & FF
                                                                          0
                                                                          Если уж CSS3, то зачем у тегов внутри классы? Почему бы не включить картинки внутрь CSS в виде data URI SVG?
                                                                            0
                                                                            Есть мнение что SVG тормозноват и глючноват, и с поддержкой плохо. Хотя мне идея побольше использовать вектор нравится, так как нет конечно никого смысла извращаться с нарезкой спрайтов с гражиентами по 2000px высотой и кучей дополнительных блоков.
                                                                              0
                                                                              Любое мнение хорошо, когда оно обоснованно. На каких фактах базируется данное мнение?
                                                                            +1
                                                                            Мне вот эта реализация понравилась:
                                                                            1) www.zurb.com/playground/super-awesome-buttons
                                                                            2) www.zurb.com/playground/radioactive-buttons

                                                                            Работает и для button, и для a. CSS3

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

                                                                            Самое читаемое