0
votes

I've a table in my project with a pseudo element to show which row is active. Having changed the table layout to fixed (which is needed), I started getting this strange layout where the active row would expand to take up the entire table, but the other rows would not:

Table width issue

I've replicated a similar problem here (codepen, snippet below) - it's not exactly the same (the active row doesn't extend), but I'm fairly sure any answer to this would help me fix my problem.

If you comment out the top active::after style you'll see the table return to its correct size.

Thanks

// TABLE DATA
const headers = ['Id', 'Name', 'Age', 'Location'];

const datasetOne = [
  ['1','John Jones','27','Swindon'],
  ['2', 'Pete Best', '23', 'Glasgow'],
  ['3', 'Jules West', '22', 'Exeter'],
  ['4', 'Kate Ford', '33', 'Fife'],
];
const datasetTwo = [
  ['5','Ruth Thompson','27','Birmingham'],
  ['6', 'Dominic Lawson', '23', 'Greater London'],
  ['7', 'Really really long name', '22', 'Manchester'],
  ['8', 'Nicholas Johnson', '33', 'Liverpool'],
];


const tableWrapper = document.querySelector('.table-wrapper');
const btn = document.querySelector('.btn');
let dataset = 1;

// Listeners
window.addEventListener('load', () => {
  const data = formatData(datasetOne);
  tableWrapper.insertAdjacentHTML('afterbegin', createTable(headers, data));
});
btn.addEventListener('click', () => {
  // Remove the table
  const table = document.querySelector('.table')
  table.parentElement.removeChild(table);

  // Create and insert a new table
  let data;
  if(dataset === 1) {
    data = formatData(datasetTwo);
    dataset = 2;
  }
  else if(dataset === 2) {
    data = formatData(datasetOne);
    dataset = 1;
  }
  tableWrapper.insertAdjacentHTML('afterbegin', createTable(headers, data));
  
})

// Functions to create the table
function formatData(data) {
    const rows = data.map(row => {
        return createHTMLRow(row);
    });
    return rows;
}
function createHTMLRow([id, name, age, location]) {
    const row = [
        `<td class="td--id">${id}</td>`,
        `<td class="td--name">${name}</td>`,
        `<td class="td--age">${age}</td>`,
        `<td class="td--location">${location}</td>`
    ];
    return row;
}
function createTable (theads, rows) {
    const markup = `
        <table class="table">
            <thead class="thead">
                <tr>
                    ${theads.map((thead) => {
                        return `<th class="th--${thead.toLowerCase()}">${thead}</th>`;
                    }).join('')} 
                </tr>
            </thead>
            <tbody class="tbody">
                ${
                    rows.map((row, index) => {
                        return `<tr class="row ${index===0? 'active':''}">${row.map(col => {
                            return `${col}`
                        }).join('')}</tr>`
                    }).join('')
                }
            </tbody>
        </table>
    `;
    return markup;
};
.active::after {
  position: absolute;
  content: '';
  left: 0;
  top: 0;
  width: 2px;
  height: 100%;
  background-color: green;
}

* {
  margin: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100vh;
  background-color: firebrick;
}


.table-wrapper {
  display: flex;
  background-color: white;
  width: 30rem;
  overflow: hidden;
}

.table {
  display: table;
  table-layout:fixed;
  border-collapse: collapse;
  overflow: hidden;
  width: 100%;
}

th {
  text-align: start;
  padding: 1rem;
  background-color: lemonchiffon;
  border: 1px solid lightgrey;
}
.th--age, .th--id {
  width: 4rem;
}

td {
  padding: .5rem 1rem;
  border: 1px solid lightgrey;
  white-space: nowrap;
}
.td--name {    
  overflow: hidden;
  text-overflow: ellipsis;
}
.row {
  position: relative;
  height: 2rem;
}



.btn {
  padding: 1rem .8rem;
  width: 7rem;
  background-color: white;
  margin-top: 2rem;
}
<div class="container">
    <div class="table-wrapper"></div>
    <div class="btn">Change Data</div>
</div>