いい感じに文字列を丸める5つの方法

# はじめに
この記事は、[オールアバウト Advent Calendar 2016](http://qiita.com/advent-calendar/2016/allabout)の14日目の記事です。

## 文字列を丸める

xx文字以上の場合は、xx文字にして最後に”…”をつける
このようなメディアあるある　をいい感じに実装する方法を
5つ（PHP, CSS3で）紹介します

# PHP
## 1. mb_strimwidth()を使う
文字を丸める！といえば`mb_strimwidth()`
これは、文字数ではなく幅を考慮して文字列をカットします
指定の文字幅より長い場合だけ、カットして最後に任意の文字列をつける事ができます

###使い方

```php
echo mb_strimwidth("メリークリスマス!", 0, 15, "...", 'UTF-8');
// メリークリス...
```

###:warning: 注意
#### 純粋に文字数で切りたい時はオススメできない
この関数は「文字幅」を対象にしています。
ざっくり言うと、全角は2, 半角は1 とカウントしているようですね。
一定文字数で丸めたいという仕様を叶えるのには微妙かもしれません。

#### 第4引数の文字幅もwidthに含まれる
これを忘れていると想定文字数より気持ち足りなくて切なくなります

```php
mb_strimwidth("abcdefg", 0, 5, "123", 'UTF-8');
echo $data;
// ab123
```

###:book: 参考
[PHPマニュアルmb_strimwidth](http://php.net/manual/ja/function.mb-strimwidth.php)
[PHP 指定した文字数で文字列を丸める。]
(http://qiita.com/musica_gatto/items/7a4043430ecce397e2f1)
[【PHP】mb_strimwidthの使い方](http://www.mikame.net/pr/archives/728)


## 2. mb_strimlen()+mb_substr()の合わせ技
純粋に文字数でぶった切り＋末尾に特定文字列をつけたいならこの方法でしょうか

以下の参考リンクではこの合わせ技で独自に関数定義する方法を紹介してます

###:book: 参考
[指定した長さで文字列を丸めるPHPの関数 mb_strimlen を作ったよ](http://www.msng.info/archives/2010/12/mb_strimlen.php)

>
>```php:↑引用
>// @see http://www.msng.info/archives/2010/12/mb_strimlen.php
>
>function mb_strimlen($str, $start, $length, $trimmarker = '', $encoding = false) {
>    $encoding = $encoding ? $encoding : mb_internal_encoding();
>    $str = mb_substr($str, $start, mb_strlen($str), $encoding);
>    if (mb_strlen($str, $encoding) > $length) {
>        $markerlen = mb_strlen($trimmarker, $encoding);
>        $str = mb_substr($str, 0, $length - $markerlen, $encoding) . $trimmarker;
>    }
>    return $str;
>}
>```

```php:実行結果
echo mb_strimlen("メリークリスマス!", 0, 7, "...", 'UTF-8');
//メリーク...
```

# CSS3 
文字を丸めることなら　クライアント側でもできますよ！

## 3. `text-overflow`　を使う
text-overflowプロパティ　`ellipsis`を使うことで
表示領域から文字列が溢れた場合、末尾を三点リーダーにした状態に出来ます

最新の全部ブラウザ対応しています
http://caniuse.com/#feat=text-overflow


### 実装

```html
<div class="box">
    <p>Wishing you a Merry Christmas and a Happy New Year</p>
</div>
```

```css
.box {
    background: #98fb98;
    overflow: hidden;
    width: 150px;
}   

.box p {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
```

####:mountain: イメージ
![2.png](https://qiita-image-store.s3.amazonaws.com/0/57611/90149a53-b5eb-7f1a-0ae1-8dca42fc10d5.png)


###:warning: 注意
####複数行対応はできない
お気づきかもしれませんが　１行のみ対応です

###:book: 参考
[MDN text-overflow](https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow)


## 4. `-webkit-line-clamp` を使う
指定した行数の最後のテキストに…を表示させるプロパティです

### 実装
```html
<div class="box">
    <p>Wishing you a Merry Christmas and a Happy New Year</p>
</div>
```

```css
.box {
    background: #98fb98;
    overflow: hidden;
    width: 150px;
}
.box p {
    margin: 0;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
}
```

####:mountain: イメージ
![3.png](https://qiita-image-store.s3.amazonaws.com/0/57611/5353c2df-bd05-5ab3-95fb-0e49ab53cf3d.png)


###:warning: 注意
#### 全ブラウザ対応していない
-webkit とprefixがついているのでお気づきかもですが

2016/12/13現在
FireFox, IE系はサポートしてないです...
http://caniuse.com/#search=line-clamp

###:book: 参考
[Line Clampin’ (Truncating Multiple Line Text)](https://css-tricks.com/line-clampin/)
[apple Safari ドキュメント](https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266-WebKit_SpecificUnsupportedProperties)


## 5. `:before,:after擬似要素`を使う
結構な無理矢理感が出ますが
現行のブラウザで複数行対応するなら以下のような感じで だいたいいけます。

### 実装
```html
<p class="ellipsis">Wishing you a Merry Christmas and a Happy New Year</p>
```

```css
.ellipsis {
    background: #98fb98;
    height: 50px;
    overflow: hidden;
    position: relative;
    width: 150px;
}

.ellipsis:before {
    bottom: 0;
    content: "…";
    right: 0;
}

.ellipsis:after {
    content: "";
    height: 100%;
    width: 100%;
}

.ellipsis:before, .ellipsis:after {
    background: #98fb98;
    position: absolute;
}
```
####:mountain: イメージ
![4.png](https://qiita-image-store.s3.amazonaws.com/0/57611/48f6e579-d395-f310-1954-263d47102ba2.png)

###:warning: 注意
#### 文字を半端な状態で丸めることがある
…は絶対位置で上に乗っけています。
つまり、中途半端な位置でも文字列を隠します。
”最後の文字が半分だけ見える”なんてこともあります...

###:book: 参考
[【複数行にも対応】長過ぎる文字列を省略して末尾を三点リーダー（…）にする方法いろいろ](https://tech.recruit-mp.co.jp/front-end/tips-ellipsis/)
[複数行にも対応！CSS を使ってはみ出した文字を「･･･」で省略する方法](http://klutche.org/archives/1725/)

# 最後に
今回は５つの方法を紹介しました！
それぞれ注意点も書いたので参考になれば幸いです。

上記の以外にも
JavaScriptで実装するなど方法は多岐に渡ると思うので
その場の要件に合わせて実装していきたいです。
（-webkit-line-clampが全ブラウザに実装されないかなー)