.ui.segment(ng-app='speechBubbles', ng-controller='mainCtrl')
  h1.ui.blue.header CSS speech bubbles the Semantic UI way
  .ui.blue.segment(ng-repeat='variant in variants')
    h2.ui.blue.header {{variant}} variant
    .ui.blue.inverted.segment(ng-repeat='pointer in pointers')
      h3.ui.header {{pointer}} pointer
      .ui.three.column.stackable.grid
        .row(ng-repeat='(direction,positions) in directions')
          .column(ng-repeat='position in positions')
            .speech(ng-class='{{[variant,pointer,"pointed",position,direction]}}')
              | .speech .{{variant}} .{{pointer}} .pointed .{{position}} .{{direction}}
View Compiled
@import "nib"

.ui.blue.inverted
  padding 5em

.speech
  position relative
  margin 1em
  padding 1.5em
  background-color white
  color black
  z-index 2
    
  &:before, &.pointed.down:before
    content ''
    position absolute
    bottom -1em
    border-style solid
    border-width 1em 1em 0
    border-color white transparent
    z-index -1
  &.pointed
    &.center:before
      right 50%
      transform translateX(50%)
    &.near::before
      left 1em
    &.far::before
      right 1em
    &.up
      &::before
        bottom auto
        top -1em
        border-width 0 1em 1em

    &.left, &.right
      &::before, &.high::before
        bottom auto
        border-color transparent white
      &.middle::before
        bottom 50%
        transform translateY(50%)
      &.low::before
        bottom 1em

    &.left::before
      left -1em
      border-width 1em 1em 1em 0
      border-color transparent white

    &.right::before
      right -1em
      border-width 1em 0 1em 1em

  &.bubble
    border-radius 1em

  &.round
    border-radius 50%
    &.pointed
      &.down, &.up
        &::before
          border 1.5em solid transparent
          border-radius 50%
          box-shadow 1em 0 0 0 white

        &.far::before
          box-shadow -1em 0 0 0 white
                
      &.left, &.right
        &::before
          border 1.5em solid transparent
          border-radius 50%
          box-shadow 0 1em 0 0 white

        &.high::before
          box-shadow 0 -1em 0 0 white
                
View Compiled
angular.module('speechBubbles', [])

.controller('mainCtrl', function ($scope) {
  $scope.variants = [
    'square',
    'bubble',
    'round'
  ];
  $scope.pointers = [
    'triangle'
  ];
  $scope.directions = {
    'down': ['near', 'center', 'far'],
    'up': ['near', 'center', 'far'],
    'left': ['high', 'middle', 'low'],
    'right': ['high', 'middle', 'low']
  };
})

;

External CSS

  1. //cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.19.3/css/semantic.min.css

External JavaScript

  1. //ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js