New Dec 1, 2025

Vuetify v-data-table fixed-header: rows visible behind rounded header when scrolling vertically in Chrome

Libraries, Frameworks, etc. All from Newest questions tagged vue.js - Stack Overflow View Vuetify v-data-table fixed-header: rows visible behind rounded header when scrolling vertically in Chrome on stackoverflow.com

How can I clip table rows under a header with rounded corners when scrolling?

When the table scrolls, the rows slide under the rounded corners of the header. Since the rows have regular (non-rounded) corners, they stick out over the header’s rounded edges. This is especially noticeable on row hover.

I tried adding a border-radius to the table wrapper:

&.table-with-header {
  :deep(.v-table__wrapper) {
    border-radius: 12px 12px 0 0;
  }
}

This works in Firefox, but not in Chrome. In Chrome, the scrollbar is inside the container but positioned to the left of the table, so the border-radius is applied to the container including the scrollbar area, and the rows are only partially clipped on the right side when scrolling.

overflow: hidden on the container doesn’t help because I need to keep the scrollbar.
clip-path: inset() didn’t work either.

How can I properly clip the table or rows exactly along the rounded header boundary? Are there any alternative approaches to fix this?

const {
  createApp
} = Vue;
const {
  createVuetify
} = Vuetify;

const vuetify = createVuetify();

const app = createApp({ data() { return { headers: [{ title: "ID", key: "id", width: "80px" }, { title: "Name", key: "name" }, { title: "Role", key: "role" }, { title: "Status", key: "status" }, ], items: Array.from({ length: 20 }, (_, i) => ({ id: i + 1, name: User ${i + 1}, role: "Administrator", status: i % 2 === 0 ? "Active" : "Offline", })), }; } });

app.use(vuetify).mount('#app');

.custom-data-table {
  --table-border: #e0e0e0;
  --header-bg: #ffffff;
  --row-hover: #f5f5f5;
}

/* Стили заголовков */
.custom-data-table .v-data-table-header th {
  border-top: 1px solid var(--table-border);
  background: var(--header-bg) !important;
  font-weight: 600 !important;
  box-shadow: none !important;
}

/* Скругление самих ячеек заголовка */
.custom-data-table .v-data-table-header th:first-child {
  border-left: 1px solid var(--table-border);
  border-top-left-radius: 12px;
}

.custom-data-table .v-data-table-header th:last-child {
  border-right: 1px solid var(--table-border);
  border-top-right-radius: 12px;
}

/* Границы тела таблицы */
.custom-data-table tbody td:first-child {
  border-left: 1px solid var(--table-border);
}

/* Стили строк */
.trRow {
  transition: background 0.2s;
}

.trRow:hover td {
  background: var(--row-hover);
}
<link href="https://cdn.jsdelivr.net/npm/vuetify@3.5.2/dist/vuetify.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">

<div id="app">
  <v-app>
    <v-main class="bg-grey-lighten-3 pa-4">
      <v-row>
        <v-col cols="12">
          <div id="tableData">
            <v-data-table :headers="headers" :items="items" :items-per-page="50" fixed-header height="400px" class="elevation-0 custom-data-table table-with-header">
              <template #headers="{ columns }">
                <tr class="v-data-table-header">
                  <th
                    v-for="header in columns"
                    :key="header.key"
                    :style="`width: ${header.width}`"
                    class="text-left"
                  >
                    <div class="py-3">{{ header.title }}</div>
                  </th>
                </tr>
              </template>

              <!-- Кастомные строки -->
              <template #item="{ item, columns }">
                <tr class="trRow">
                  <td v-for="col in columns" :key="col.key">
                    {{ item[col.key] }}
                  </td>
                </tr>
              </template>
            </v-data-table>
          </div>

        </v-col>
      </v-row>
    </v-main>
  </v-app>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3.5.2/dist/vuetify.min.js"></script>

Scroll to top