このエントリーをはてなブックマークに追加

Truncation, Flexbox, and Tables

Truncation

When you have a long string of text that you want to restrict to one line, but not let it grow forever and ever, you have to truncate it. Truncating text can be a nightmare. The standard way of truncating text is with a CSS component like this:

.truncate {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

Then you just have to apply it to an element with text.

It Just Works

Playground Link →

<div class="max-w-md flex gap-16 w-full mx-auto justify-center">
  <p class="truncate">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sodales
    elit quis vulputate pretium. In hac habitasse platea dictumst. Praesent
    scelerisque dolor sit amet volutpat aliquam. Phasellus ultrices sollicitudin
    metus. Cras sit amet sem nibh. Pellentesque lacinia enim eget lacinia
    dignissim. Donec iaculis fringilla suscipit. Phasellus non lobortis quam. Ut
    rutrum ex eu suscipit dignissim. Fusce elementum rutrum risus sit amet
    posuere. Sed ac sollicitudin arcu. Mauris interdum lorem sed mi sodales
    placerat.
  </p>
</div>

This just works. All you need is the .truncate class and for the parent of the text block to have a width or max-width. The browser takes care of everything. This starts to break a little when you’re using flexbox though.

Flexbox Fail

Playground Link →

<div class="max-w-md flex gap-16 w-full mx-auto justify-center">
  <div>
    <p class="truncate">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      sodales elit quis vulputate pretium. In hac habitasse platea dictumst.
      Praesent scelerisque dolor sit amet volutpat aliquam. Phasellus ultrices
      sollicitudin metus. Cras sit amet sem nibh. Pellentesque lacinia enim eget
      lacinia dignissim. Donec iaculis fringilla suscipit. Phasellus non
      lobortis quam. Ut rutrum ex eu suscipit dignissim. Fusce elementum rutrum
      risus sit amet posuere. Sed ac sollicitudin arcu. Mauris interdum lorem
      sed mi sodales placerat.
    </p>
  </div>
</div>

Min-Width Trick

If the text you’re trying to truncate is inside a flex child, the truncate trick won’t work. The way around this is to apply min-width: 0px to the flex child.

Playground Link →

<div class="max-w-md flex gap-16 w-full mx-auto justify-center">
  <div class="min-w-0">
    <p class="truncate">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
      sodales elit quis vulputate pretium. In hac habitasse platea dictumst.
      Praesent scelerisque dolor sit amet volutpat aliquam. Phasellus ultrices
      sollicitudin metus. Cras sit amet sem nibh. Pellentesque lacinia enim eget
      lacinia dignissim. Donec iaculis fringilla suscipit. Phasellus non
      lobortis quam. Ut rutrum ex eu suscipit dignissim. Fusce elementum rutrum
      risus sit amet posuere. Sed ac sollicitudin arcu. Mauris interdum lorem
      sed mi sodales placerat.
    </p>
  </div>
</div>

Tables

The above methods should let you truncate text in every situation, except tables. Because…tables.

The Problem with Tables

Playground Link →

<table>
  <thead>
    <tr>
      <th class="p-2 text-left">Flexible Width</th>
      <th class="p-2 text-left">Short Width</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="p-2 truncate">
        Bacon ipsum dolor amet meatball ground round chicken, hamburger cupim
        sirloin doner burgdoggen porchetta capicola kevin ham.
      </td>
      <td class="p-2">
        <div class="flex items-center gap-4">
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
        </div>
      </td>
    </tr>
  </tbody>
</table>

The problem you’ll run into with tables is that when you have a td, it has no real width. It just takes up the space it’s given. If you apply our .truncate class, the text in the cell will explode outside of the td. You can give it a width or give it a max-width, and it works, but you lose the flexible sizing the browser gives you by default.

Playground Link →

<table>
  <thead>
    <tr>
      <th class="p-2 text-left">Flexible Width</th>
      <th class="p-2 text-left">Short Width</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="p-2 max-w-sm truncate">
        Bacon ipsum dolor amet meatball ground round chicken, hamburger cupim
        sirloin doner burgdoggen porchetta capicola kevin ham.
      </td>
      <td class="p-2">
        <div class="flex items-center gap-4">
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
        </div>
      </td>
    </tr>
  </tbody>
</table>

The Table Cell Fix

The fix for table cells without a width/max-width is not that difficult to implement, but there’s a trick to making it flexible. You need to make the td a flex container, wrap your content in a div that has flex: 1 1 0% and width: 0px set, and then add your content inside with our .truncate class. The flex settings might make sense, but the width is weird. You need to tell the width to be 0px so that it will be as small as possible, but can flex as large as there is space available.

Playground Link →

<table class="min-w-full w-full">
  <thead>
    <tr>
      <th class="p-2 text-left">Flexible Width</th>
      <th class="p-2 w-0 text-left">Short Width</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="mt-1.5 p-2 flex">
        <div class="flex-1 w-0 truncate">
          Bacon ipsum dolor amet meatball ground round chicken, hamburger cupim
          sirloin doner burgdoggen porchetta capicola kevin ham.
        </div>
      </td>
      <td class="p-2">
        <div class="flex items-center gap-4">
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
          <button class="bg-blue-600 text-white rounded-md shadow py-1 px-3">
            Button
          </button>
        </div>
      </td>
    </tr>
  </tbody>
</table>

There’s a slight problem with this method. Table cells do not want to be flex containers. They lose their default vertical alignment. They do not know how tall the row they are in is, so you cannot make them fill the tr’s height. You have to add margin-top by sight to make the td’s content vertically centered. It’s not great, but it is the best you can do.

And One More Thing…

If for some reason you have a fieldset inside your new truncate/flex combo, it will not work.

Playground Link →

<td class="mt-1.5 p-2 flex">
  <div class="flex-1 w-0">
    <fieldset class="">
      <span class="block truncate">
        Bacon ipsum dolor amet meatball ground round chicken, hamburger cupim
        sirloin doner burgdoggen porchetta capicola kevin ham.
      </span>
    </fieldset>
  </div>
</td>

The problem is fieldsets do not behave like other normal elements. You can make it work though. The trick is making the fieldset be min-width: 0px. This will trick the fieldset into shrinking like other elements can because a fieldset has a standard min-width of whatever its content is.

Playground Link →

<td class="mt-1.5 p-2 flex">
  <div class="flex-1 w-0">
    <fieldset class="min-w-0">
      <span class="block truncate">
        Bacon ipsum dolor amet meatball ground round chicken, hamburger cupim
        sirloin doner burgdoggen porchetta capicola kevin ham.
      </span>
    </fieldset>
  </div>
</td>

Truncation is a necessary tool for many UIs. Hopefully, if you find yourself needing it in a table, you’ll be able to handle it without any problem in the future!


このエントリーをはてなブックマークに追加

SymfonyWorld 2021から約半年、 いよいよ明日6/17からSymfonyWorld 2021 Summer Editionのカンファレンスパートが始まります。 https://live.symfony.com/2021-world/

今回、2日目の6/18に Can your code live without the Symfony framework? というタイトルで登壇します。日本時間6/18金曜日の17:50〜です。
https://live.symfony.com/2021-world/schedule#session-595
英語で登壇するのは初めてで、録画提出済とはいえ、既にとてもドキドキしています :sweat_drops:

タイトルでお察しかと思いますが、3月に PHPerKaigi 2021で話した内容 をSymfonyユーザー向けに書き直した内容になります。 実はCall For PaperとしてはSymfonyWorldのほうに先に応募していたのですが、PHPerKaigiのほうが実際の開催が早く、先に日本でお披露目となったお題でした。
日本版(?)でちょっと最後言葉足らずだったかなという部分も補足を入れました。

オンラインなのでチケットまだまだ購入可能です。
海外カンファレンスの常でややお高めとなっているのですが、もしお時間ある方いれば聞きに来て応援してください!SymfonyWorldのチケットは他のトークの録画も後日何度でもリプレイ可能なので意外とお得ですよ。


このエントリーをはてなブックマークに追加

産休&育休から復帰した志賀です :baby:

ちょうど 前回の記事 が産休直前で、そこから約1年ぶりの記事となります。

復帰直後は、リハビリという名の小さめタスクをやらせていただいてました。

そのおかげでどうにか調子も戻ってきてコードもバリバリ書いてます!(自称)

そこで今回は復帰後〜1ヶ月のリハビリと称された期間でやったことを紹介します :information_desk_person:

おまけでコードが書けなくなるのが怖くて休暇中にやっていたこともご紹介できたらなと思います。

復帰後〜1ヶ月(リハビリ期間)にやったこと

私はPHPチームに所属しており、リーダーからリハビリ期間でふってもらったタスクはこんな感じのものでした。

  • URLの変更
  • 既存APIのレスポンス項目の追加
  • API調査

保育園から呼び出し等の心配をしていただいた上で期限にゆとりがあるものや優先度低めのものを中心にふってもらいました :bow:

タスクをこなしつつSymfonyを思い出していました。

テストの書き方を結構忘れており、既存コードを参考にさせてもらい改めて勉強になりました。

おまけ

私の場合、特に妊娠中は暇なせいか「コードが書けなくなったらどうしよう」と不安になることがあったので、たまにコードを書いたり本を読んだりしてました。

その中でやっていたことを紹介します。

  • ぴよログや授乳ノートみたいなLINE:left_right_arrow:スプレットシートで記録できるアプリを作った。(結局、授乳ノートで記録してましたが、最近は記録さえしてないです。)
  • デザインパターンの本(「Head First デザインパターン」 )を再読した。
  • 育児ブログ書こうかなと思ってワードプレスでブログ作った。(育児が忙しくなってもう更新してないですw)
  • ペチコンやPHPerKaigi、Symfony Meetup Kansaiに参加した。(オンラインのため育児中でも参加しやすかったです。)

妊娠中は体調も良くて暇だったのでもっと本読んだりコード書いたりしておけば良かったな〜と思いました。

子どもが生まれると時間が作れずほぼコードを書く時間はなくなりました。そのおかげか今は昔よりコード書きたい欲が増した気がします!:star2:

今思えばいい充電期間だったのかなと思います。

子どもが生まれて改めて育児しながらお仕事してる方はすごいな〜と尊敬しました。とくにカルテット開発部はママさん・パパさんが多いので本当に尊敬してます!

そして自分も無理はせず、育児と仕事両立できるかっこいい母になりたいな〜:sunglasses:と思いました。

カルテットでは子の看護休暇があったり、私は会社まで少し遠いこともありリモートワークで働かせてもらったりと柔軟な対応のおかげでとても働きやすく楽しくコードを書けてます。