Анимированные кнопки произвольной ширины на CSS3

    Перед нами стояла задача сверстать универсальную кнопку только на HTML и CSS, не имеющую фиксированного размера по ширине, которая в дефолтном состоянии отображает только иконку, а при наведении будет показываться текст внутри неё.

    image

    Казалось бы, вот же оно — очевидное и простое решение:

    .button {
      transition: width ease-out 0.2s;
      width: 32px;
    }
    .button:hover {
      transition: width ease-out 0.2s;
      width: auto;
    }
    

    Но css transition в этом случае не отрабатывает.

    Когда раньше ко мне приходили и спрашивали — «а можно ли так сделать на CSS3?», я разочаровывал дизайнеров и менеджеров, порицая эдакий недопил в css-свойстве transition.

    И все таки оказалось, что одна лазейка есть, причем простая до безобразия.

    Вместо width надо заюзать max-width:

    .button {
      transition: width ease-out 0.2s;
      max-width: 32px;
    }
    .button:hover {
      transition: width ease-out 0.2s;
      max-width: 300px;
    }
    

    Та же сама история применима, когда нам надо «поиграться» с height.

    Демо и исходный код можно посмотреть там же, во вкладках html и css.

    Спасибо за внимание!
    Share post

    Similar posts

    Comments 35

      –23
      Имхо анимация слишком быстрая.

      PS: Каммент к демке " ╭∩╮(︶︿︶)╭∩╮ "
        +3
        Владимир, так лучше по-человечески это написать, вместо ни о чем не говорящих карикатур.
          +1
          Нет нет, эта карикатура не выражает мое мнение, наоборот, мне вполне понравилось, только анимация слишком резкая.
            +1
            Исправил на более плавную анимацию, спасибо за фидбек.
              +2
              Вы знаете, у знака «плюс» скорость анимации должна быть медленнее раза в два по сравнению с минусом. Иначе создрается впечатление что знак «минус» делает два оборота, а «плюс» — четыре.
                +1
                да, ты прав, это видимо из-за отсутствия вертикальной полосы :) исправил.
        0
        Сделайте в демо анимацию разворачивания чуть подольше, пожалуйста, а то кажется что ее и нет.

        А так способ хороший, сам давно искал, а оказалось просто до безобразия, спасибо
          0
          Исправил.
          0
          Анимации почти не видно, вместо неё мерцание и кнопка всё равно не развёрнутая остаётся в итоге.
          Linux Ubuntu 12.10
          Google Chome 23.0.1271.97
          Intel Celeron Dual Core 2.1 ГГц / RAM 2GB
            0
            проверь сейчас, должно быть норм.
              0
              К сожалению, ничего не изменилось. Из расширений только AdBlock и FlashBlock.
            +2
            Не очень понятно, зачем в данном случае анимация. Пользователь нажмет на кнопку быстрее, чем она развернется.
              –1
              Имхо для эстетики, иначе зачем вообще выпендриваться со стилями и просто использовать обычные нативные кнопки.
                –1
                Здесь эстетика ради эстетики. В данном случае удобства она не несёт. И даже наоборот отвлекает, как и сказал выше товарищ Retarded. Я подношу мышку к кнопке, чтобы нажать, а получаю в ответ анимацию, которая отвлекает моё внимание, затягивает нажатие.
                  0
                  Верно подмечено, но нужно выбирать между нескольких зол когда есть утвержденный дизайн или есть потребность разгрузить визуальное пространство на сайте, или когда хочется сделать что-то красивое на сайте чтобы придать отличительную черту или особенность.
                  Хочу обратить внимание — кейс с кнопками не ограничивает нас в использовании этого приёма.
                    0
                    А если прикрутить js, ну или переверстать, чтобы при попадании курсора в определённый радиус от кнопки она разворачивалась, например 200px;
              +1
              <span class="button_icon"></span> вот этот пустой код лишний, чем вас :after :before не устраивает, раз вы делаете все по современным правилам?
                0
                Несомненно я начинал делать с :before и :after, но в процессе выяснил что на данный момент эти спевдоэлементы не поддерживают transition. И это несомненный fail =\
                  +3
                    0
                    Спасибо! Не знал.
                    0
                    Да ладно? Уже не раз обсуждалось сие на хабре. Firefox вполне поддерживает анимацию псевдо элементов (кстати, правильнее с двумя "::" писать), а у Chrome'а уже тона прошений пользователей к разработчикам, чтобы решили сей вопрос…
                    • UFO just landed and posted this here
                  +1
                  Не то чтобы это не работало, но все таки работает не совсем так как задумано. Анимация разгоняется так, будто собирается перейти от 32px до 960px, но потом резко прерывается (когда контент уже помещается). В итоге анимация заканчивается быстрее, и функция смягчения искажается (от нее берется как бы кусок).

                  Чтобы минимизировать этот эффект нужно наоборот указывать max-width как можно меньше.
                    0
                    Всё верно, я думаю над вариантом выставления значения max-width функцией attr(), которая будет брать значение из аттрибута тэга. В этом случае есть минус — придется использовать немного javascript'a.
                      0
                      Так это ведь нигде не работает, так что и смысла пробовать в данный момент нет.
                        0
                        Кхм-кхм, в каком это смысле нигде не работает?

                        Internet Explorer 8.0+
                        Chrome 2.0+
                        Opera 9.0+
                        Safari 3.1+
                        Firefox 1.0+
                        Android 1.0+
                        iOS 1.0+
                          0
                          Там таблица из 3-х строк, прочтите нижнюю ;).
                            0
                            в этом случае первая строчка, то есть «Basic support» меня устроит, так как я буду брать строковое значение аттрибута и вставлять его в псевдоэлемент через свойство content
                              0
                              А как выставить значение свойства «max-width» CSS-функцией attr() тогда?
                    0
                    А как делается вращение?
                      0
                      Используя свойство transform: rotate(360deg);
                      +5
                      На самом деле решение далеко не новое и это не решение проблемы, а костыль, ибо вместо анимирования за n времени у вас получается анимирование с n скоростью, да и свойство «min-*» в большинстве подобных случаях подбирается на глаз и вполне себе не резиновое, что опровергает заголовок статьи (произвольной ширины...) :).
                      • UFO just landed and posted this here
                          +1
                          А где же ширина произвольная, если она жетская в пикселях?
                            0
                            Применимо не только к этому топику, а вообще к таким всем демкам на «чистом CSS3!»
                            у меня в браузере отключен javascript по умолчанию (NoScript), мне не трудно включить конечно, но когда ждешь этот самый чистый CSS, то странно видеть что выключенном JS не отображается вообще ничего.
                            Просто не первый раз уже на хабре, вот решил выразить недовольство в комментариях.

                            Only users with full accounts can post comments. Log in, please.