New Feb 23, 2026

Fluid colums with fixed header element [closed]

Libraries, Frameworks, etc. All from Newest questions tagged vue.js - Stack Overflow View Fluid colums with fixed header element [closed] on stackoverflow.com

I've got a table with table-layout="auto" for autowidth of the columns, and height=400 for the fixed header, but the scroll overflows the header which should not happen.

With table-layout="fixed" the scroll will fix, but the columns will not get all the width. It uses Vue3 and the library component element plus.

<template>
  <el-table
    height="400"
    :data="internalData"
    :default-sort="defaultSort"
    @sort-change="$emit('sort-change', $event)"
    style="width: 100%"
    border
    class="custom-table"
    table-layout="fixed"
    overflow-x="auto"
    @row-click="handleRowClick"
  >
    <el-table-column
      v-for="col in columns"
      :key="col.prop"
      :prop="col.prop"
      :label="col.label"
      :width="col.width"
      :min-width="col.minWidth"
      :sortable="col.sortable ? 'custom' : false"
    >
    </el-table-column>
  </el-table>
</template>

<script setup lang="ts"> import { ref, onBeforeMount, watch } from 'vue'

// Define props and emits (añadí desync para debugging) const props = defineProps<{ data: Record<string, any>[], columns: any[], desync?: boolean }>()

defineEmits(['sort-change'])

const handleRowClick = (row: any) => { console.log(row) }

// defaultSort definido antes del render const defaultSort = ref({ prop: 'id', order: 'ascending' as 'ascending' | 'descending' | null, // Element Plus usa 'ascending'/'descending' })

// datos internos que usa la tabla (permite simular desincronía) const internalData = ref<Record<string, any>[]>([])

function applySort(arr: Record<string, any>[], sort: { prop?: string; order?: string | null }) { if (!sort?.prop || !sort.order) return const prop = sort.prop const order = sort.order === 'ascending' ? 1 : -1 arr.sort((a, b) => { if (a[prop] == null) return 1 * order if (b[prop] == null) return -1 * order if (a[prop] > b[prop]) return 1 * order if (a[prop] < b[prop]) return -1 * order return 0 }) }

function shuffle(arr: Record<string, any>[]) { // Fisher–Yates for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)) ;[arr[i], arr[j]] = [arr[j], arr[i]] } }

// inicializar antes del primer render onBeforeMount(() => { internalData.value = props.data ? [...props.data] : [] if (props.desync) { // para reproducir el bug: la UI se muestra en orden distinto al sort por defecto shuffle(internalData.value) // mantiene defaultSort para la cabecera pero la lista mostrada está desordenada } else { // aplicar sort por defecto antes del render para evitar flicker applySort(internalData.value, defaultSort.value) } })

// si los datos externos cambian, sincronizar respetando el modo desync watch( () => props.data, (newData) => { internalData.value = newData ? [...newData] : [] if (props.desync) { shuffle(internalData.value) } else { applySort(internalData.value, defaultSort.value) } }, { immediate: false } ) </script>

<style scoped> :deep(.cell) { white-space: nowrap !important; } </style>

How can I fix it? I need a mix between table-layout="fixed" and table-layout="auto" for full width columns.

Scroll to top