Search code examples
htmlcssmaterialize

Truncate span inside td


I'm using Materialize classes to create a "photo placeholder" to the user which contains the first letter of his name.

I'm having trouble with long names inside the <td> tag. I do not want the name to break when it's too long. Because of that, I've tried to apply class="truncate" into the spam that contains the name, but it failed to truncate.

How can I solve this?

main {
  padding: 16px;
}

table {
  table-layout: fixed;
}

td {
  width: 33.33%;
}

.photo-placeholder {
  width: 40px;
  height: 40px;
  line-height: 40px;
  border-radius: 50%;
  text-align: center;
  display: inline-block;
  background-color: crimson;
  color: white;
}

.truncate {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

<main>

  <table id="table1" class="white z-depth-1 centered">
    <thead>
      <tr>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td data-label="Col 1">
          <span class="photo-placeholder">P</span>
          <span class="truncate">Pedro Luis Arend Gonçalves</span>
        </td>
        <td data-label="Col 2">Info 2</td>
        <td data-label="Col 3">Info 3</td>
      </tr>
    </tbody>
  </table>

</main>

JSFiddle

Expected result:

enter image description here


Solution

  • It seems that the "truncate" class sets the element to display:block, which puts it on its own line.

    One solution might be to set it to display:inline-block and set it's width to the remaining space in the table cell. Below, I've calculated the appropriate width by using calc(). I've also eliminated the white space between the two <span> elements so it won't contribute extra width.

    main {
      padding: 16px;
    }
    
    table {
      table-layout: fixed;
    }
    
    td {
      width: 33.33%;
    }
    
    .photo-placeholder {
      width: 40px;
      height: 40px;
      line-height: 40px;
      border-radius: 50%;
      text-align: center;
      display: inline-block;
      background-color: crimson;
      color: white;
    }
    
    #table1 .truncate {
      display: inline-block;
      width: calc(100% - 40px);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <main>
    
      <table id="table1" class="white z-depth-1 centered">
        <thead>
          <tr>
            <th>Col 1</th>
            <th>Col 2</th>
            <th>Col 3</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td data-label="Col 1">
              <span class="photo-placeholder">P
              </span><span class="truncate">Pedro Luis Arend Gonçalves</span>
            </td>
            <td data-label="Col 2">Info 2</td>
            <td data-label="Col 3">Info 3</td>
          </tr>
        </tbody>
      </table>
    
    </main>

    To avoid having to calculate the width, you can simply float the placeholder left, like this:

    main {
      padding: 16px;
    }
    
    table {
      table-layout: fixed;
    }
    
    td {
      width: 33.33%;
    }
    
    .photo-placeholder {
      float: left;
      width: 40px;
      height: 40px;
      line-height: 40px;
      border-radius: 50%;
      text-align: center;
      background-color: crimson;
      color: white;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <main>
    
      <table id="table1" class="white z-depth-1 centered">
        <thead>
          <tr>
            <th>Col 1</th>
            <th>Col 2</th>
            <th>Col 3</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td data-label="Col 1">
              <span class="photo-placeholder">P</span>
              <span class="truncate">Pedro Luis Arend Gonçalves</span>
            </td>
            <td data-label="Col 2">Info 2</td>
            <td data-label="Col 3">Info 3</td>
          </tr>
        </tbody>
      </table>
    
    </main>

    Here's a different method that uses a flexbox container. I like this one because it's easier to vertically center the two elements with align-items:center.

    main {
      padding: 16px;
    }
    
    table {
      table-layout: fixed;
    }
    
    td {
      width: 33.33%;
    }
    
    .photoContent {
      display: flex;
      align-items: center;
    }
    
    .photo-placeholder {
      flex: 0 0 40px;
      height: 40px;
      line-height: 40px;
      border-radius: 50%;
      text-align: center;
      background-color: crimson;
      color: white;
      margin: 0 0.5em 0 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <main>
    
      <table id="table1" class="white z-depth-1 centered">
        <thead>
          <tr>
            <th>Col 1</th>
            <th>Col 2</th>
            <th>Col 3</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td data-label="Col 1">
              <div class="photoContent">
                <span class="photo-placeholder">P</span>
                <span class="truncate">Pedro Luis Arend Gonçalves</span>
              </div>
            </td>
            <td data-label="Col 2">Info 2</td>
            <td data-label="Col 3">Info 3</td>
          </tr>
        </tbody>
      </table>
    
    </main>