css overflow hidden を使用すると前後の要素の位置がおかしくなる

表示領域を固定して「overflow:hidden + text-overflow:ellipsis;」を使用して、領域以上の文字は 「…」で表示するというのは、よく使うトリックである。

しかし、chrome以外では、inline-boxの要素にoverflow:hiddenを指定すると表示位置が微妙にずれる。

「Stack Overflow」にも同じような内容の投稿がある。

http://stackoverflow.com/questions/4310047/css-why-is-vertical-align-baseline-stop-working-on-firefox-when-using-overflow
[overflow]未指定
firefox15(ずれない)chrome21(ずれない)
[overflow:hidden]指定
firefox15(ずれる)chrome21(ずれない)

firefoxだけがおかしいのではなく、IEでも同じように表示される。

ちなみに、inline-block要素にvertical-align:middleを指定すると、それなりに中央位置へ要素が配置されるが、前後の要素とは、ずれる。
位置のずれが少しであるため、よけいみっともない。
[overflow:hidden vertical-align:middle]指定
firefox15(ずれる)chrome21(ずれる)

本題

overflow:hiddenを使用する箇所が少ないのであれば、marginや、paddingの値を中央に配置するよう微調整すればよいが、大量にある場合はそれぞれを調整するのは困難である。

なので、overflow:hiddenを指定しないで、同じように表示する仕組みを考えてみた。
まずHTMLの定義。
 
<div class="inline-block test4" data-dummy="test test ...">
test test test test
</div>

div要素が、表示領域を固定する対象。
ここでキモになるのが、「data-dummy」属性。ここに、表示領域内におさまるよう整形し、省略文字をつけた文字列を記述する。div要素内の文字列はそのまま。

そしてCSS
 
.test4:before {
  content:attr(data-dummy);
  color:green;
}
.test4 {
  color:transparent;
}

:beforeで、data-dummyの値を参照し、出力するよう設定する。
実データは、文字の色を透明に変えて実質非表示にする。
これで、要素内の値を加工することなく、「over-flow:hidden + text-overflow:ellipsis;」を実現できた。
beforeを使用
firefox15chrome21
テスト用に作ったHTML
 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
 body {
   font-size:24px;
 }
 input {
   padding:0;
   font-size:24px;
   width:100px;

 }
 table {
   border-spacing:10px;
 }
 td {
    margin:5px;
   padding:10px;
   border: 1px solid black;
 background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAIAAADkharWAAAAHklEQVQokWPsmfOLgRTA+P//f5I0MJGkelTD0NUAAEKBBTZu9j5PAAAAAElFTkSuQmCC) repeat scroll 0 0 transparent;
  }
 .inline-block {
   display:inline-block;
   width:100px;
   white-space:nowrap;
   background-color:#AAA;
   border: 1px solid blue;
   color:green;
 }
 .test1 {
 }
 .test2 {
   overflow:hidden;
   text-overflow:ellipsis;
 }
 .test3 {
   overflow:hidden;
   text-overflow:ellipsis;
   vertical-align:middle;
 }
 .test4:before {
   content:attr(data-dummy);
   color:green;
 }
 .test4 {
   color:transparent;
 }

</style>

<script type="text/javascript">
</script>
</head>
<body>

<table>
 <tr>
  <td>
   abc
   <div class="inline-block test1">
    test test test test
   </div>
   <input type="text" value="test" />
   abc
  </td>
 </tr>
 <tr>
  <td>
   abc
   <div class="inline-block test2">
    test test test test
   </div>
   <input type="text" value="test" />
   abc
  </td>
 </tr>
 <tr>
  <td>
   abc
   <div class="inline-block test3">
    test test test test
   </div>
   <input type="text" value="test" />
   abc
  </td>
 </tr>
</table>
<br/>
<table>
 <tr>
  <td>
   abc
   <div class="inline-block test4" data-dummy="test test ...">
    test test test test
   </div>
   <input type="text" value="test" />
   abc
  </td>
 </tr>
</table>

</body>
</html>

コメント

このブログの人気の投稿

itext 5.3.0 で UniJIS-UCS2-HW-H を指定した場合、欧文文字の幅がおかしい

IEで画面遷移時にgif画像でローディンングのアニメーションを表示