Created
November 7, 2013 09:30
-
-
Save Tenderfeel/7351752 to your computer and use it in GitHub Desktop.
CSS Speech Bubble Mixin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- | |
// CSS Speech Bubble Mixin | |
// _bubble.scss | |
// | |
// http://jsdo.it/Tenderfeel/ApPq | |
//--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- | |
// # bubble-tail-init | |
// | |
// しっぽのベース作成 | |
// before,after疑似要素を使用するため、他の目的では利用できなくなる | |
// bubble-tailを使用する場合に、`$init`をtrueにするなら不要。 | |
// | |
// `$before` -- before疑似要素(輪郭線) | |
// `$after` -- after疑似要素(塗り) | |
// | |
// ```SCSS | |
// div { | |
// @include bubble-tail-init(false, true); | |
// } | |
// ``` | |
// | |
@mixin bubble-tail-init($before:true, $after:true) { | |
@if $before == true and $after == true { | |
&::before, &::after { | |
content:' '; | |
width: 0px; | |
height: 0px; | |
display: block; | |
position: absolute; | |
border-style: solid; | |
} | |
} | |
@if $before == true and $after == false { | |
&::before { | |
content:' '; | |
width: 0px; | |
height: 0px; | |
display: block; | |
position: absolute; | |
border-style: solid; | |
} | |
} | |
} | |
// # bubble-tail | |
// | |
// しっぽ本体作成 | |
// before疑似要素を`$borderColor`で塗り潰し、 | |
// `$bgColor`で塗り潰したafter疑似要素を上に重ねて表現する。 | |
// 枠線がある場合、しっぽの大きさを超える太さにすると背景色のしっぽが消えて線だけになる。 | |
// 向きは [triangle generator](http://apps.eky.hk/css-triangle-generator/)と同じ。 | |
// | |
// `$direction` -- 向き(top, top right, right, bottom right, bottom, bottom left, left, top left) | |
// `$width` -- 横幅 | |
// `$height` -- 高さ | |
// `$borderColor` -- 線色 | |
// `$bgColor` -- 背景色 | |
// `$init` -- 疑似要素の初期化をするかどうか | |
// `$top` -- top位置指定 | |
// `$left` -- left位置指定 | |
// `$right` -- right位置指定 | |
// `$bottom` -- bottom位置指定 | |
// | |
// ```SCSS | |
// div { | |
// @include bubble-tail('left', 10px, 14px, #FFF, 2px, #0099FF); | |
// } | |
// ``` | |
// | |
@mixin bubble-tail( | |
$direction, | |
$width, | |
$height, | |
$bgColor, | |
$borderWidth:0, | |
$borderColor:transparent, | |
$top:null, | |
$right:null, | |
$bottom:null, | |
$left:50%, | |
$init:true | |
) { | |
//疑似要素初期設定 | |
@if $init == true { | |
@if $borderWidth > 0 { | |
@include bubble-tail-init(true, true); | |
} @else { | |
@include bubble-tail-init(true, false); | |
} | |
} | |
$w :ceil($width/2); | |
$h :ceil($height/2); | |
@if $borderWidth == 0 { | |
$borderColor: $bgColor; | |
} | |
//枠線分だけ引いたサイズ | |
$b2:$borderWidth*2; | |
$wb :$width - $borderWidth; | |
$wb2 :$width - $b2; | |
$w2b :$w - $borderWidth; | |
$w2b2:$w - $b2; | |
$hb :$height - $borderWidth; | |
$h2b :$h - $borderWidth; | |
$hb2 :$height - $b2; | |
//下向き | |
@if $direction == 'bottom' { | |
&::before { | |
border-width:$height $w 0 $w; | |
border-color: $borderColor transparent transparent transparent; | |
bottom:-$height; | |
margin-left:-($width/2); | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
//下向き枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width:$hb ceil($wb2/2) 0 ceil($wb2/2); | |
border-color: $bgColor transparent transparent transparent; | |
bottom:-$hb2; | |
margin-left:-$w2b; | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
} | |
}//bottom | |
//上向き | |
@if $direction == 'top' { | |
&::before { | |
border-width: 0 $w $height $w; | |
border-color: transparent transparent $borderColor transparent; | |
top:-$height; | |
margin-left:-$w; | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
//上向き枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width:0 ceil($wb2/2) $hb ceil($wb2/2); | |
border-color: transparent transparent $bgColor transparent; | |
top:-($hb2 + 1); | |
margin-left:-$w2b; | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
} | |
}//top | |
//右向き | |
@if $direction == 'right' { | |
&::before { | |
border-width: $h 0 $h $width; | |
border-color: transparent transparent transparent $borderColor; | |
right:-$width; | |
margin-top:-$h; | |
@if $top { | |
top:$top; | |
} @else { | |
top:50%; | |
} | |
} | |
//右向き枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width:ceil($hb2/2) 0 ceil($hb2/2) $wb; | |
border-color: transparent transparent transparent $bgColor; | |
right:-$wb2; | |
margin-top:ceil(-$hb2/2); | |
@if $top { | |
top:$top; | |
} @else { | |
top:50%; | |
} | |
} | |
} | |
}//right | |
//左向き | |
@if $direction == 'left' { | |
&::before { | |
border-width: $h $width $h 0; | |
border-color: transparent $borderColor transparent transparent; | |
left:-$width; | |
margin-top:-$h; | |
@if $top { | |
top:$top; | |
} @else { | |
top:50%; | |
} | |
} | |
//左向き枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width:ceil($hb2/2) $wb ceil($hb2/2) 0; | |
border-color: transparent $bgColor transparent transparent; | |
left:-$wb2; | |
margin-top:ceil(-$hb2/2); | |
@if $top { | |
top:$top; | |
} @else { | |
top:50%; | |
} | |
} | |
} | |
}//left | |
@if $direction == 'topleft' { | |
&::before { | |
border-width:$height $width 0 0; | |
border-color: $borderColor transparent transparent transparent; | |
bottom:-$height; | |
margin-left:0; | |
@if $left { | |
left:$left; | |
} @else { | |
left:25%; | |
} | |
} | |
//枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width:$hb $wb2 0 0; | |
border-color: $bgColor transparent transparent transparent; | |
bottom:-$hb2; | |
margin-left:$borderWidth; | |
@if $left { | |
left:$left; | |
} @else { | |
left:25%; | |
} | |
} | |
} | |
}//topleft | |
@if $direction == 'topright' { | |
&::before { | |
border-width:0 $width $height 0; | |
border-color: transparent $borderColor transparent transparent; | |
bottom:-$height; | |
margin-right:0; | |
@if $right { | |
right:$right; | |
} @else { | |
right:50%; | |
} | |
} | |
//枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width: 0 $wb2 $hb 0; | |
border-color: transparent $bgColor transparent transparent; | |
bottom:-$hb2; | |
margin-right:$borderWidth; | |
@if $right { | |
right:$right; | |
} @else { | |
right:50%; | |
} | |
} | |
} | |
}//topright | |
@if $direction == 'bottomleft' { | |
&::before { | |
border-width:$height 0 0 $width; | |
border-color: transparent transparent transparent $borderColor; | |
top:-$height; | |
margin-left:0; | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
//枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width: $hb 0 0 $wb; | |
border-color: transparent transparent transparent $bgColor; | |
top:-$hb2; | |
margin-left:$borderWidth; | |
@if $left { | |
left:$left; | |
} @else { | |
left:50%; | |
} | |
} | |
} | |
}//bottomleft | |
@if $direction == 'bottomright' { | |
&::before { | |
border-width:0 0 $height $width; | |
border-color: transparent transparent $borderColor transparent; | |
top:-$height; | |
margin-right:0; | |
@if $right { | |
right:$right; | |
} @else { | |
right:50%; | |
} | |
} | |
//枠線付き | |
@if $borderWidth > 0 { | |
&::after { | |
border-width: 0 0 $hb $wb; | |
border-color: transparent transparent $bgColor transparent; | |
top:-$hb2; | |
margin-right:$borderWidth; | |
@if $right { | |
right:$right; | |
} @else { | |
right:50%; | |
} | |
} | |
} | |
}//bottomright | |
}//bubble-tail |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment