Group several table columns and overflow to left - html

I want to display a kind of competitions results table. Each row has a participant name, followed by several cells representing participant results in last competitions (say, the competitions take place once per week). Something like this:
User name Aug 1 Aug 8 Aug 15
John Doe 1 10 100
Jane Doe 100 10 1
The table may become very wide if many columns are present. In such a case, I want the oldest columns to be hidden, so that only a few most recent are visible, and the table does not overflow the available space. The user name columns should always be visible.
The "borderline" cells can be "cut" like this:
User name g 1 Aug 8 Aug 15
John Doe 1 10 100
Jane Doe 00 10 1
...or they can be completely invisible, both variants are acceptable to me.
It is possible to achieve this with pure css?
For just one line, I've achieved it without a table, using display: flex together with direction: rtl for the 'columns' only:
https://jsfiddle.net/fo2Ldk3n/
.outer {
width: 350px;
display: flex;
justify-content: flex-right;
border: 1px solid black;
}
.header {
white-space: nowrap;
margin-right: 10px;
}
.line-box {
direction: rtl;
overflow: hidden;
white-space: nowrap;
}
.line {
padding-right: 10px;
display: inline;
white-space: nowrap;
}
<div class="outer">
<div class="header">
User Name
</div>
<div class="line-box">
<div class="line">
2223 +1
</div>
<div class="line">
10
</div>
<div class="line">
100
</div>
<div class="line">
1
</div>
<div class="line">
10
</div>
<div class="line">
100
</div>
<div class="line">
1
</div>
<div class="line">
10
</div>
<div class="line">
100
</div>
<div class="line">
1
</div>
</div>
</div>
However, this obviously fails for several rows, because the numbers will not be aligned into columns:
I've tried to use colgroup and set display: rtl etc. for the results col, but it would not work.
Also note that direction: rtl results in wrong order of 'words' within a cell (see 1+ 2223, which should be 2223 +1). The latter is not really a big problem, as I will mostly have only numbers in the cells, so it's ok if the solution has this problem. But it'll be better if it does not.

I've got it. The key is to use table wrapped into div with direction: rtl, this gives cells going from right to left and overflowing to the left. And use position: absolute for user names.
An additional direction: ltr on td even makes cell content render in correct direction.
.outer {
width: 300px;
border: 1px solid black;
position: relative;
direction: rtl;
overflow: hidden;
}
.table {
white-space: nowrap;
}
.row td {
direction: ltr;
}
.header {
position: absolute;
left: 0;
background: white;
padding-right: 10px;
}
<div class="outer">
<table class="table">
<tr class="row">
<td>1 + 100</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td class="header">User name</td>
</tr>
<tr class="row">
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td>1</td>
<td>10</td>
<td>100</td>
<td>1000</td>
<td class="header">Long long user name</td>
</tr>
</table>
</div>
The user name cells have different widths, but this seems to me.

Related

How to adjust the table and make to display without gaps? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
Here is how it should look
Here how it looks
`
https://codepen.io/SevastianBah/pen/VwBaPVB
`
I suppose that it is related some how to the big red block. In code inspector, there is no any margins or paddings for block.
I have gone through your code pen. You tried to demonstrate the table using nested table inside the tag. However it can may be fulfill your target. But using colspan and rowspan property you can easily demonstrate the table.
Here I have demonstrated it using colspan rowspan. Well the concept is pretty easier. Look carefully at your targeted table. There you can easily equally divided each cells in total 4 rows and 3 columns. Where the 1st cell taken two column and two row. So we declared colspan value 2 and rowspan value 2. These will allow the cell to take two rows and two column. then the rest td will represent other cells. So as 1st td taken 2 columns and two rows so in 1st and second rows total td will be 3 and 2. but in third row each td will take one cell.
In css the border collapse will remove the spaces in between. Then you can add border to each td. Go through the code below. Hope this might help you.
table{
width: 600px;
height: 400px;
border-collapse: collapse;
}
td{
border: 2px solid black
}
<!DOCTYPE html>
<html>
<head>
<title>Table</title>
</head>
<body>
<table>
<tr>
<td style='background-color: red' colspan='2' rowspan='2'></td>
<td style='background-color: blue'></td>
<td style='background-color: red'></td>
</tr>
<tr>
<td style='background-color: red'></td>
<td style='background-color: blue'></td>
</tr>
<tr>
<td style='background-color: red'></td>
<td style='background-color: blue'></td>
<td style='background-color: red'></td>
<td style='background-color: blue'></td>
</tr>
</table>
</body>
</html>
Float td left:
td{
margin: 0;
padding: 0;
float: left;
}
.big{
width: 240px;
height: 240px;
}
.small{
width: 120px;
height: 120px;
}
.red{
background-color: red;
}
.blue{
background-color: blue;
}
div{
border: 2px black solid;
}
td{
margin: 0;
padding: 0;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link href="/css/style.css" type="text/css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<table>
<tr>
<td><div class="big red"></div></td>
<td>
<table>
<tr>
<td><div class="small blue"></div></td>
<td><div class="small red"></div></td>
</tr>
<tr>
<td><div class="small red"></div></td>
<td><div class="small blue"></div></td>
</tr>
</table>
</td>
</tr>
<tr>
<td><div class="small red"></div></td>
<td><div class="small blue"></div></td>
<td><div class="small red"></div></td>
<td><div class="small blue"></div></td>
</tr>
</table>
</body>
</html>

Angular *ngFor to generate table 4 cells wide

I have an array in a component file that will by dynamically updated based on a database query. I need this array to be populating the contents of a table like this:
For an array of 7 items:
---------------------------------------------
| array[0] | array[1] | array[2] | array[3] |
---------------------------------------------
| array[4] | array[5] | array[6] |
----------------------------------
I have this method so far:
HTML:
<table>
<ng-container *ngFor="let employer of businessAdmins">
<tr>
<div class="card shadow m-2" style="height:25vh;width:18.75vh;border-radius:5%;overflow:hidden;">
<div class="ml-1"><div style="font-weight:bold">Name: </div>{{employer.data().first_name + " " + employer.data().last_name}}</div>
</div>
</tr>
</ng-container>
</table>
This works fine in producing a list of cells however I do not know how to populate them horizontally until there are 4 horizontal cells and then move on to the next line.
It is very simple with CSS flex box. Try this code -
HTML
<div class="table">
<ng-container *ngFor="let employer of businessAdmins">
<div class="card shadow">
<div style="font-weight:bold">
Name: {{employer.data().first_name + " " + employer.data().last_name}}
</div>
</div>
</ng-container>
</div>
CSS
.table {
display: flex;
flex-wrap: wrap;
width: 100%;
.card {
flex: 1 0 25%;
}
}
Result-
You can do something like this (manually) as I was not able to find the "step" in *ngFor so far (I've simplified your employer as simple string).
I don't like it as it's not using any advantage of the framework and we are scanning the list/array even if we don't need every element (performance issue).
<table>
<ng-container *ngFor="let employer of businessAdmins; let i = index">
<tr *ngIf="i % 4 == 0">
<td> {{ businessAdmins[i] }} </td>
<td *ngIf="businessAdmins[i+1]"> {{ businessAdmins[i+1] }} </td>
<td *ngIf="businessAdmins[i+2]"> {{ businessAdmins[i+2] }} </td>
<td *ngIf="businessAdmins[i+3]"> {{ businessAdmins[i+3] }} </td>
</tr>
</ng-container>
</table>
You can acheive it with flex box.
flexbox
td {
width: 20%;
background-color: aqua;
border: 1px solid black;
}
tr {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
height: 100%;
}
table {
width: 40vw;
margin: 30px
}
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
</table>

Clip long text inside HTML table cells, show entire content on hover

I have a table html table which has a column named "address". The address contains very long strings. What I want is I only want to show first 2 or 3 words of the address and when I hover over it, it should show full address. How can I do this with html table?
Solution:
Use table-layout: fixed so that your table columns maintain fixed size
Wrap the content inside div elements and manipulate width and overflow properties
/*
* fixed table layout
*/
table {
table-layout: fixed;
width: 400px;
font: larger monospace;
border-collapse: collapse;
}
th:nth-child(1) {
width: 20%;
}
th:nth-child(3) {
width: 20%;
}
/*
* inline-block elements expand as much as content, even more than 100% of parent
* relative position makes z-index work
* explicit width and nowrap makes overflow work
*/
div {
display: inline-block;
position: relative;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
}
/*
* higher z-index brings element to front
* auto width cancels the overflow
*/
div:hover {
z-index: 1;
width: auto;
background-color: #FFFFCC;
}
<table border="1">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td><div>John Smith</div></td>
<td><div>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div></td>
<td><div>1-234-567890</div></td>
</tr>
<tr>
<td><div>Jane Doe</div></td>
<td><div>Suspendisse lacinia, nunc sed luctus egestas, dolor enim vehicula augue.</div></td>
<td><div>1-234-567890</div></td>
</tr>
</tbody>
</table>
.cell {
max-width: 50px; /* tweak me please */
white-space : nowrap;
overflow : hidden;
}
.expand-small-on-hover:hover {
max-width : 200px;
text-overflow: ellipsis;
}
.expand-maximum-on-hover:hover {
max-width : initial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table border="1">
<thead>
<tr>
<th>
ID
</th>
<th>
Adress
</th>
<th>
Comment
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td class="cell expand-maximum-on-hover">
A very, very long adress that cannot be showed entirely
</td>
<td class="cell expand-small-on-hover">
A very, very long comment to add more information to the row it belongs to.
</td>
</tr>
</tbody>
</table>
You might begin from there, this is an example of how to use max-width combined with overflow : hidden.
Pass hover the adress cell to see the result
Using Tootips gives a solution,
<html>
<table border="1" >
<tr>
<td>A</td>
<td><abbr title="Ab df df dfdf df dfdkjf sdfk dfdf">Ab df df</abbr> </td>
</tr>
<tr>
<td>B</td>
<td><abbr title="Bb df df dfdf df dfdkjf sdfk dfdf">Bb df df</abbr> </td>
</tr>
</table>
</html>

Setting fixed height for all rows of the table

I have created a table http://jsfiddle.net/vR5B8/.
table id="resultDetails" class="table-striped" border=1 width="99%" nowrap=0; cellspacing=0; cellpadding=3><tbody>
<th colspan="2"><Big>Result Details</Big></th>
<tr data-depth=0 class="collapse" height=1px >
<td width="4%">P</td>
<td width="80%">Modules
<div class="content">
<p>Abc</p>
</div>
</td>
</tr>
<tr data-depth=0 class="collapse" height=1px >
<td width="4%">P</td>
<td width="80%">Modules 1</td>
</tr>
<tr data-depth=0 class="collapse" height=1px >
<td width="4%">P</td>
<td width="80%">Modules 2</td>
</tr>
</tbody>
Some of the rows contain additional information which is hidden. If the row contains hidden information, then the height of row is increasing compare to the row which does not contain the hidden information. How to set the common height for all rows.
Any thoughts ?
Use display: none instead of visibility hidden demo
tr {
height: 50px;
}
for example :) or
tr {
height: auto;
}
depends of what you need :)
The table row height will increase dynamically in height if more information is added, but to hide an element, use display: none and to give a height to a row, use line-height: /* size */;
.content {
display:none;
}
tr {
min-height: 20px;
line-height: 20px;
}
Here's the jsFiddle

How to vertically align HTML text as in a column

I'd like to have HTML that looks like this:
we already know that: 2*1 = 2
2*2 = 4
2*3 = 6
(i.e., the numbers are aligned as in a column)
I could use a table, or maybe text-indent.
I'd like to know other options, and what, if any, is "the right way".
My Two cents for a more semantic, non-table solution:
<div class="content">we already know that:</div>
<div class="math">
<div class="eq">
<span class="operand">2</span><span class="operator">*</span><span class="operand">1</span><span class="operator">=</span><span class="result">2</span>
</div>
<div class="eq">
<span class="operand">2</span><span class="operator">*</span><span class="operand">2</span><span class="operator">=</span><span class="result">4</span>
</div>
<div class="eq">
<span class="operand">2</span><span class="operator">*</span><span class="operand">3</span><span class="operator">=</span><span class="result">2</span>
</div>
<div class="eq">
<span class="operand">2</span><span class="operator">*</span><span class="operand">300</span><span class="operator">=</span><span class="result">600</span>
</div>
</div>
.content {float:left;}
.math {float:left;}
.math .operand {width: 3em;display: inline-block; }
.math .operator {padding-left: 5px; padding-right:5px }
.math .result {font-weight:bold; text-align:right;width:3em;display: inline-block; }
However, having seen the extra markup and reviewing what you have I think a table is actually your best solution. You have a table of data with 5 columns, two operand columns, two operator columns and one result column.
http://jsfiddle.net/vnMM2/
UPdate Table Version (quick and dirty conversion)
<div class="content">we already know that:</div>
<table class="math">
<tr class="eq">
<td class="operand">2</td>
<td class="operator">*</td>
<td class="operand">1</td>
<td class="operator">=</td>
<td class="result">2</td>
</tr>
<tr class="eq">
<td class="operand">2</td>
<td class="operator">*</td>
<td class="operand">2</td>
<td class="operator">=</td>
<td class="result">4</td>
</tr>
<tr class="eq">
<td class="operand">2</td>
<td class="operator">*</td>
<td class="operand">3</td>
<td class="operator">=</td>
<td class="result">2</td>
</tr>
<tr class="eq">
<td class="operand">2</td>
<td class="operator">*</td>
<td class="operand">300</td>
<td class="operator">=</td>
<td class="result">600</td>
</tr>
</table>
.content {float:left;}
.math {float:left;}
.math td { text-align:right}
.math .result {font-weight:bold }
http://jsfiddle.net/vnMM2/2/
Use a <pre> tag. Quote from w3Schools:
Text in a <pre> element is displayed in a fixed-width font (usually Courier), and it preserves both spaces and line breaks.
Or if that is not an option for you, you can use CSS to set any element to preserve white space by adding white-space: pre; .
I am little confused. I am not sure, I may answer you properly.
If you want to have the Superscript, follow this code:
"2 <sup>1</sup> = 2
2 1 = 2
2 2 = 2
Likewise.