WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

文字列の長さ制限、三点リーダー表示

by WebSurfer 2023年6月23日 13:52

先の記事「GridView に overflow 適用、三点リーダー表示」で、CSS の overflow: hidden と text-overflow: ellipsis を使って文字列の長さ制限するとともに三点リーダーを表示する例を紹介しましたが、文字列の中にエスケープされた文字、プロポーショナルフォント、サロゲートペア、絵文字などが含まれる場合どうなるかという話を書きます。

文字列の長さ制限、三点リーダー表示

上の画像の下側の表の description 列の各行が、文字列の長さを 320px に制限するとともに末尾を三点リーダーで表示したものです。具体的にどのようにしたかと言うと、上側の表の description 列と同じ文字列を div 要素に入れて、その div 要素に以下の CSS を適用しました。ブラウザは Chrome、フォントはメイリオ、サイズは 16px です。

<style type="text/css">
    div.style1
    {
        width: 320px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }
</style>

1 行目にある < > & という文字は、実際は &lt; &gt; &amp; というエスケープされた文字列が、ブラウザ上では < > & と表示されたものです。

4 行目の絵文字 🍎 と 🍏 は UTF-16 のサロゲートペア (🍎 は 0xD83C 0xDF4E, 🍏 は 0xD83C 0xDF4F) です。👨‍🌾 は、👨 と 🌾 (おのおのサロゲートペアで 0xD83D 0xDC68 と 0xD83C 0xDF3E) を ZeroWidthJoiner (0x200D) で連結したもの、つまり、0xD83D 0xDC68 0x200D 0xD83C 0xDF3E となっています。

上の結果から分かるように、各文字の長さやバイト数とは関係なく、ブラウザ上に表示された文字列の長さで制限がかかり、CSS の width: 320px で指定された幅いっぱいに三点リーダを含めて表示されています。

上の画像ではフォントはメイリオ、サイズは 16px ですが、MS Gothic などの等幅フォントを使った場合も、フォントサイズを変えた場合も、ブラウザ上に表示される文字列の長さで制限がかかるのは同じです。

三点リーダーを表示する text-overflow:ellipsis はもともと IE の独自拡張だそうですが、最近は他のブラウザでも取り入れられているようです。Windows 10 で Chrome 114.0.5735.134, Edge 114.0.1823.58, Firefox 114.0.2, Opera 100.0.4815.21 で試してみましたが、同じ結果が得られました。

参考に、上の画像を表示するのに使った ASP.NET Web Forms アプリのコードを載せておきます。

.aspx.cs

using System;
using System.Data;

namespace WebForms1
{
    public partial class WebForm26 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // データソースとして DataTable を作成。
                DataTable dt = new DataTable();
                DataRow dr;

                dt.Columns.Add(new DataColumn("id", typeof(Int32)));
                dt.Columns.Add(
                    new DataColumn("description", typeof(string)));

                dr = dt.NewRow();
                dr["id"] = 1;
                dr["description"] = "エスケープされた < > & " +
                    "などの文字はどのようになるか?";
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["id"] = 2;
                dr["description"] = "Proportional Font WWWWWWWWWWW " +
                    "iiiiiiii llllll などは?";
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["id"] = 3;
                dr["description"] = "サロゲートペア 𠀋 𡈽 𠮟 などは" +
                    "どのようになるか?";
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["id"] = 4;
                dr["description"] = "絵文字 🍎 🍏 (サロゲートペア) " +
                    "👨‍🌾 (ZWJ で結合) などは?";
                dt.Rows.Add(dr);

                // 上で作成した DataTable を GridView にバインド。
                GridView1.DataSource = dt;
                GridView1.DataBind();

                GridView2.DataSource = dt;
                GridView2.DataBind();
            }
        }
    }
}

.aspx

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="WebForm26.aspx.cs" Inherits="WebForms1.WebForm26" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <style type="text/css">
        body {
            font-family: "メイリオ";
            font-size: 16px;
        }

        div.style1 {
            width: 320px;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <p>制限しない場合 (フォント: メイリオ, 16px)</p>
        <asp:GridView ID="GridView1"
            runat="server"
            AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="id" />
                <asp:TemplateField HeaderText="description">
                    <ItemTemplate>
                        <asp:Literal ID="Literal1"
                            runat="server"
                            Text='<%# Eval("description") %>'>
                        </asp:Literal>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

        <p>overflow:hidden で制限 (フォント: メイリオ, 16px)</p>
        <asp:GridView ID="GridView2"
            runat="server"
            AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="id" />
                <asp:TemplateField HeaderText="description">
                    <ItemTemplate>
                        <div class="style1">
                            <asp:Literal ID="Literal1"
                                runat="server"
                                Text='<%# Eval("description") %>'>
                            </asp:Literal>
                        </div>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </form>
</body>
</html>

Tags: , , , ,

ASP.NET

GridView に overflow 適用、三点リーダー表示

by WebSurfer 2015年11月10日 14:04

GridView の列に長い文字列を入れると、下の画像の「制限しない場合」のように文字列の長さに応じて列の幅が広がっていってしまいます。

それを下の画像の「overflow:hidden で制限」のように、CSS の overflow を使って決まった範囲内に制限する方法について書きます。(テキストが領域をこえた場合に三点リーダー「…」を表示することもできます。詳しくはこの記事の下の方の 2015/11/12 追記を見てください)

GridView に overflow 適用

ASP.NET が GridView を html コードにレンダリングすると table, tr, th, td 要素になります。BoundField を使うと文字列は td 要素の中に直接配置されます。

td 要素はブロックレベル要素ではないのでそれに直接 overflow は適用できません。なので、td 要素の中に div 要素を 配置しそれに overflow 他のスタイルを適用した上で div 要素内に文字列を入れるのがよさそうです。

クライアント側だけで JavaScript を使っても可能ですが、ASP.NET のコードで対応した方が簡単そうです。

具体的には、当該列を TemplateField に変換し、それに div 要素を配置して overflow 他のスタイルを適用、div 要素の中に Literal コントロールを配置してその Text プロパティをデータバインドします。

そのコード例は以下の通りで、これを実行すると上の画像の結果になります。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!IsPostBack)
    {
      // データソースとして DataTable を作成。
      DataTable dt = new DataTable();
      DataRow dr;

      dt.Columns.Add(new DataColumn("id", typeof(Int32)));
      dt.Columns.Add(
          new DataColumn("description", typeof(string)));

      dr = dt.NewRow();
      dr["id"] = 1;
      dr["description"] = "グリッドビューはデータソースの"+ 
                          "値を表に表示します。";
      dt.Rows.Add(dr);

      dr = dt.NewRow();
      dr["id"] = 2;
      dr["description"] = "The GridView displays the " + 
                      "values of a data source in a table.";
      dt.Rows.Add(dr);

      // 上で作成した DataTable を GridView にバインド。
      GridView1.DataSource = dt;
      GridView1.DataBind();

      GridView2.DataSource = dt;
      GridView2.DataBind();
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>GirdView に overflow 適用</title>
  <style type="text/css">
    div.style1
    {
      width: 150px;
      height: 1.1em;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <h2>制限しない場合</h2>
  <asp:GridView ID="GridView1" runat="server">
  </asp:GridView>

  <h2>overflow:hidden で制限</h2>
  <asp:GridView ID="GridView2" 
    runat="server" 
    AutoGenerateColumns="False">
    <Columns>
      <asp:BoundField DataField="id" HeaderText="id" />
      <asp:TemplateField HeaderText="description">
        <ItemTemplate>
          <div class="style1">
            <asp:Literal ID="Literal1" 
              runat="server" 
              Text='<%# Eval("description") %>'>
            </asp:Literal>
          </div>
        </ItemTemplate>
      </asp:TemplateField>
    </Columns>
  </asp:GridView>
  </form>
</body>
</html>

------ 2015/11/12 追記 ------

テキストが領域をこえた場合に三点リーダー「…」を表示する text-overflow:ellipsis はもともと IE の独自拡張だそうですが、最近は他のブラウザでも取り入れられているようです。下の画像は、自分の環境 Vista SP2 32-bit で、Opera 12.17 で試した結果です。

text-overflow:ellipsis 適用

IE9, Chrome 46.0.2490.86 m, Firefox 42.0, Safari 5.1.7 でも同様に text-overflow:ellipsis は有効でした。(古いバージョン、その他のブラウザは未確認です)

上の画像の例ではスタイルを以下のように変更しています。

<style type="text/css">
    div.style1
    {
        width: 150px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }
</style>

Tags: ,

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar