Pull to refresh

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

Reading time 3 min
Views 28K

Предисловие


Многое, ранее сделанное с использованием 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
Tags:
Hubs:
-3
Comments 13
Comments Comments 13

Articles