Предисловие
Многое, ранее сделанное с использованием 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; }
Наглядное объяснение того, как этот метод работает:

Как выравнить треугольник по центру вертикали?
Для начала напомню о том, что элемент 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
