kloffy
kloffy

Reputation: 2928

Vuetify data table component - Truncate text in cell using CSS

In the following example, is there any way to use CSS to truncate the text in the cell (rather than have it wrap around or overflow)? Ideally, the CSS should look something like this:

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

But as you can see below, this just causes the cell to consume all the space:

<!DOCTYPE html>
<html>
<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  <style>
.truncate {
  display: inline-block;
  /* width: 200px; */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
  </style>
</head>
<body>
  <div id="app">
<v-app>
  <v-content>
    <v-data-table :headers="headers" :items="items">
      <template v-slot:item.name="{ item }">
        <span class="truncate">{{ item.name}}</span>
      </template>
    </v-data-table>
  </v-content>
</v-app>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
  <script>
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: {
    headers: [
      { text: 'Name', value: 'name', width: "75%" },
      { text: 'Calories', value: 'calories', width: "25%" },
    ],
    items: [
      { name: 'Frozen Yogurt', calories: 159, },
      { name: 'Ice cream sandwich with a really, really, really long name that keeps going on and on and on forever so there is no space left', calories: 237, },
      { name: 'Eclair', calories: 262, },
    ], }
})
  </script>
</body>
</html>

It is possible to achieve the desired effect by specifying a fixed width in pixels, but I would like the table and its columns to be responsive.

Upvotes: 4

Views: 13092

Answers (3)

hobbes_child
hobbes_child

Reputation: 141

Your code works if you just change the SPAN to a DIV and uncomment the width in the css.

<!DOCTYPE html>
<html>
<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  <style>
.truncate {
  display: inline-block;
  width: 200px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
  </style>
</head>
<body>
  <div id="app">
<v-app>
  <v-content>
    <v-data-table :headers="headers" :items="items">
      <template v-slot:item.name="{ item }">
        <div class="truncate">{{ item.name}}</div>
      </template>
    </v-data-table>
  </v-content>
</v-app>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
  <script>
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: {
    headers: [
      { text: 'Name', value: 'name', width: "75%" },
      { text: 'Calories', value: 'calories', width: "25%" },
    ],
    items: [
      { name: 'Frozen Yogurt', calories: 159, },
      { name: 'Ice cream sandwich with a really, really, really long name that keeps going on and on and on forever so there is no space left', calories: 237, },
      { name: 'Eclair', calories: 262, },
    ], }
})
  </script>
</body>
</html>

Upvotes: 0

jssDev
jssDev

Reputation: 993

It worked for me by setting the css max-with value to a responsive vw value:

    .truncate {
       max-width: 50vw;
       white-space: nowrap;
       overflow: hidden;
       text-overflow: ellipsis;
    }

Upvotes: 1

S&#248;lve
S&#248;lve

Reputation: 4406

If you apply the truncating to the td instead, and applying the magic hack max-width: 1px you will get your desired result.

In the example below, in order to apply the class to the td you have to use the item slot and create the row yourself.

<!DOCTYPE html>
<html>

<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  <style>
    .truncate {
      max-width: 1px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  </style>
</head>

<body>
  <div id="app">
    <v-app>
      <v-content>
        <v-data-table :headers="headers" :items="items">
          <template v-slot:item="{ item }">
            <tr>
              <td class="truncate">{{ item.name}}</td>
              <td>{{ item.calories}}</td>
            </tr>
          </template>
        </v-data-table>
      </v-content>
    </v-app>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
  <script>
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: {
        headers: [{
            text: 'Name',
            value: 'name',
            width: "75%"
          },
          {
            text: 'Calories',
            value: 'calories',
            width: "25%"
          },
        ],
        items: [{
            name: 'Frozen Yogurt',
            calories: 159,
          },
          {
            name: 'Ice cream sandwich with a really, really, really long name that keeps going on and on and on forever so there is no space left',
            calories: 237,
          },
          {
            name: 'Eclair',
            calories: 262,
          },
        ],
      }
    })
  </script>
</body>

</html>

Upvotes: 12

Related Questions