Balloon средствами CSS

Предисловие


Многое, ранее сделанное с использованием JS, можно реализовать средствами CSS, часто это упрощает некоторые задачи. В статье будет рассказано о том, как выравнить треугольную стрелку балуна по середине по вертикали и о том, как избежать использования изображения для отрисовки этого самого треугольника.


Для начала — листинг всего кода


HTML разметка (далее будет изложено о реализации без span'а с пробелом внутри)

<p class="balloon">
    <span class="arrow"> </span>My CSS balloon
</p>


CSS

.balloon{
    position:absolute; left:40px; top:20px;
    width:200px; height:auto; /* высота подстраивается под контент */
    background:#fff; padding:10px;
    -webkit-border-radius:6px; -moz-border-radius:6px; border-radius:6px;
}
    .balloon>.arrow{
        position:absolute; left:-10px; top:50%; 
        margin-top:-10px;
        display:block;
        width: 0px;
        height: 0px;
        border-top: 10px solid transparent;
        border-bottom: 10px solid transparent;
        border-right: 10px solid #fff;
    }


А теперь, по порядку


Как нарисовать треугольник средствами CSS?

.balloon>.arrow{
        width: 0px;
        height: 0px;
        border-top: 10px solid transparent;
        border-bottom: 10px solid transparent;
        border-right: 10px solid #fff;
}


Наглядное объяснение того, как этот метод работает:
image


Как выравнить треугольник по центру вертикали?

Для начала напомню о том, что элемент A с абсолютным позиционированием, обернутый в элемент B с относительным (или абсолютным) позиционированием, будет иметь нулевые координаты в верхнем левом углу элемента B (т.е. будет позиционироваться внутри элемента B)

.balloon{ position:absolute; }
    .balloon>.arrow{ position:absolute; }


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

top = balloonHeight/2 - arrowHeight/2

Но, мы не можем получить высоту балуна средствами CSS. Есть красивый способ это обойти.

Выравним треугольник по Y на 50-ти процентах высоты балуна (замена balloonHeight/2)

.balloon>.arrow{
        position:absolute; top:50%; 
}


Из половины высоты балуна, необходимо вычесть половину высоты треугольника:

.balloon>.arrow{
        position:absolute; top:50%; 
        margin-top:-10px;
}


Аналогичным образом реализуется выравнивание по центру горизонтали.

Демо


Со статичной высотой: jsfiddle.net/mdQzH/362
С динамической высотой: jsfiddle.net/mdQzH/465


Релизация с использованием селектора :before и свойства content


По просьбе dshster

HTML

<p class="balloon">
        Balloon
</p>


CSS

.balloon{
        display:block;
        position:absolute; left:40px; top:20px;
        width:200px; height:auto; /* высота подстраивается под контент */
        background:#fff; padding:10px;
        -webkit-border-radius:6px; -moz-border-radius:6px; border-radius:6px;
}

.balloon:before{
        content: '.';
        position:absolute; left:-10px; top:50%; margin-top:-10px;
        display:block;
        width: 0px;
        height: 0px;
        border-top: 10px solid transparent;
        border-bottom: 10px solid transparent;
        border-right: 10px solid #fff;
}


Демо


jsfiddle.net/mdQzH/474


Balloon с тенью


По просьбе niko83

HTML

<p class="balloon">
        Balloon
</p>


CSS

.balloon{
        display:block;
        position:absolute; left:40px; top:10px;
        width:200px; height:auto;
        background:#fff; padding:10px;
        -webkit-border-radius:6px; -moz-border-radius:6px; border-radius:6px;
        moz-box-shadow:0 0 7px #bbb; -webkit-box-shadow:0 0 7px #bbb; box-shadow:0 0 7px #bbb;
}
        .balloon:before{
                content:" ";
                position:absolute; left:-10px; top:50%; margin-top:-10px; z-index:1;
                display:block;
                width: 0px;  height: 0px;
                border-top: 10px solid transparent;
                border-bottom: 10px solid transparent;
                border-right: 11px solid #fff; /* увеличено на единицу для сокрытия тени от подложки */
        }

        .balloon:after{
                content:" ";
                position:absolute; left:0px; top:50%; margin-top:-2px-; z-index:0;
                display:block;
                width: 4px; height: 4px;
                moz-box-shadow:-8px 0 7px #555; -webkit-box-shadow:-8px 0 7px #555; box-shadow:-8px 0 7px #555;
        }


Под большой треугольник подкладывается блок меньшего размера, так, чтобы он был вписан в треугольник. Ему и присваивается стиль с тенью. Нужно учесть, что тень по краям имеет цвет, менее насыщенный, поэтому в примере цвет тени #555, а не #bbb

Демо


jsfiddle.net/mdQzH/586
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 13

    +1
    Для `height:0;width:0;` картинку, вероятно, лучше было бы перерисовать.

    Потому что не совсем очевидно, почему при таких параметрах справа появляется треугольник.
      –5
      Люди, имеющие опыт в разметке, поймут
        +5
        Людям, имеющим опыт в разметке, этого и объяснять совсем не нужно, если уж на то пошло.
      +1
      А почему бы не использовать селектор :after/content для создания стрелки? Если уж переходить на css, то избавляться декоративных от тегов:

      jsfiddle.net/dmitry_shvalyov/z5ehT/
        0
        Действительно :before помог бы реализовать тот же эффек но уже без лишних элементов (правда не во всех браузерах), плюс эта методика не годиться если заказали балуны с тенями
          +6
          Спасибо за незабываемый урок которому уже наверное года 4.
          habrahabr.ru/post/107259/
          nicolasgallagher.com/pure-css-speech-bubbles/
          stackoverflow.com/questions/8866736/css-speech-bubble-with-box-shadow
          www.sitepoint.com/pure-css3-speech-bubbles/

          Хватит постить простейшие вещи которые уже многие года все используют!

          А про фигуры на css читаем тут habrahabr.ru/post/126207/
            –2
            О каких сложных вещах написать?
              0
              Хотя бы о тем которые уже не были упомянуты на хабре раз 10
            0
            Когда я делал такой balloon, у меня возникла проблема. Не получалось сделать нормальную тень. Тень от треугольника накладывалась на тело пузыря. Был бы признателен если модернизируете свой пример чтоб такое пузырь содержал тень. Пузырь ведь находится над плоскостью сайта и должен отбрасывать тень. Спасибо.
              0
              Есть вариант — подложить под треугольник блок с тенью. Тень, возможно, будет не абсолютно равномерной на краях, но, как по мне, так это неплохой вариант, правда в IE8 тени не будет, впрочем, как и округленных уголков

              Для lt IE8 можно сделать границу, а чтобы сделать границу у треугольника, нужно подложить под него треугольник цвета границы, с шириной границ на 1px больше (зависит от толщины границ)
              +1
              В первых двух примерах выравнивание что-то не совсем по-вертикали…
                0
                1. Так писать не стоит, что хром что лиса уже как пару лет использует эти атрибуты без префиксов.
                -webkit-border-radius:6px; -moz-border-radius:6px; border-radius:6px;
                -moz-box-shadow:-8px 0 7px #555; -webkit-box-shadow:-8px 0 7px #555; box-shadow:-8px 0 7px #555;

                2. Не стоит писать единицы измерения, если указываете 0.
                width: 0px;

                3. Что за крайней не уклюжий стиль написания цсс в комбинированном виде? Одни правила идут столбик, другие в строчку.

                4. Что не статья о цсс\хтмл из песочницы, то яркий пример как делать не стоит.
                  –2
                  2-4 — субъективно

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