How to text ellipsis with width auto / dynamically? - html

I have a table where I group all the orders of a user. The product name row is often very large, so the text comes out of the table and breaks the layout of the entire page.
To solve this I am using text ellipsis with a max-width: 200px;. This is fine on desktop, but when I switch to tablet or mobile the 200px width is no longer fine.
So I would have to change max-width every time according to the browser display width (mobile, tablet, portrait etc ..), this is insane.
So is there any way to make the width of text ellipsis work automatically? Or determine the width of the text ellipsis based on the row width percentage ?
To better explain the problem
I used a wide range of media queries for the convenience of the question. .product_name is 100% wide and that's what I want.
.product_name> a on the other hand has a fixed width of 200px, so even if the screen gets bigger or smaller, the product name is always displayed with the same width.
To solve this problem I would have to use different media queries and change the max-width of .product_name> a every time, which I want to avoid.
Is there a way to tell the max-width to automatically fit the width of td.product name ?
/*Global Container For Table*/
.global_container.order {
gap: 12px;
}
/* Table Width */
.product_number { width: 10%; }
.product_name { width: 35%; }
.product_data { width: 15%; }
.product_price { width: 10%; }
.product_status { width: 15%; }
.product_action { width: 15%; }
/* Table Heading */
.table_orders.heading > tbody > tr > td {
color: #4B525F;
font-weight: 600;
}
.table_orders.heading {
border: solid #e0e0e0;
border-width: 0px 0px 1px 0px;
padding: 0px 0px 12px 0px;
width: 100%;
}
/* Table Orders */
.table_orders {
text-align: left;
border: 0;
font-weight: 400;
color: #737477;
padding-top: 12px;
width: 100%;
}
td {
border: 0;
font-size: 13px;
}
/* Text Ellipsis */
.product_name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
/*** Mobile Device Range ***/
#media only screen and (min-width: 280px) and (max-width: 1024px){
.table_orders.heading { display: none; }
/* Name Before Value */
.product_number::before { content: 'Ordine'; }
.product_name::before { content: 'Prodotto'; }
.product_data::before { content: 'Data'; }
.product_price::before{ content: 'Prezzo'; }
.product_status::before { content: 'Stato'; }
.product_action::before { content: 'File'; }
/* Items */
.product_name {
white-space: unset;
overflow: unset;
text-overflow: unset;
max-width: unset;
}
.product_name > a {
text-align: right;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 200px;
}
td {
display: flex;
width: 100%!important;
flex-direction: row;
justify-content: space-between;
}
}
<table class="table_orders heading">
<tr class="table_row">
<td class="product_number">Order ID</td>
<td class="product_name">Product Name</td>
<td class="product_data">Date</td>
<td class="product_price">Total</td>
<td class="product_status">Status</td>
<td class="product_action">File</td>
</tr>
</table>
<table class="table_orders">
<tr class="table_row_items">
<td class="product_number">
<span>#12345</span>
</td>
<td class="product_name">
Product Name is very long long long long long long long long long long long
</td>
<td class="product_data">
<span>02/08/2022</span>
</td>
<td class="product_price">
<span>Order Total</span>
</td>
<td class="product_status">
<span>Purchuased</span>
</td>
<td class="product_action">
Show
</td>
</tr>
</table>

Use #media to change css based on screen size.
Example:
#media only screen and (max-width: 600px) {
.product_name {
max-width: 100px;
}
}
Code:
/*Global Container For Table*/
.global_container.order {
gap: 12px;
}
/* Table Width */
.product_number { width: 10%; }
.product_name { width: 35%; }
.product_data { width: 15%; }
.product_price { width: 10%; }
.product_status { width: 15%; }
.product_action { width: 15%; }
/* Table Heading */
.table_orders.heading > tbody > tr > td {
color: #4B525F;
font-weight: 600;
}
.table_orders.heading {
border: solid #e0e0e0;
border-width: 0px 0px 1px 0px;
padding: 0px 0px 12px 0px;
width: 100%;
}
/* Table Orders */
.table_orders {
text-align: left;
border: 0;
font-weight: 400;
color: #737477;
padding-top: 12px;
width: 100%;
}
td {
border: 0;
font-size: 13px;
}
/* Text Ellipsis */
.product_name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
#media only screen and (max-width: 600px) {
.product_name {
max-width: 100px
}
}
<table class="table_orders heading">
<tr class="table_row">
<td class="product_number">Order ID</td>
<td class="product_name">Product Name</td>
<td class="product_data">Date</td>
<td class="product_price">Total</td>
<td class="product_status">Status</td>
<td class="product_action">File</td>
</tr>
</table>
<table class="table_orders">
<tr class="table_row_items">
<td class="product_number">
<span>#12345</span>
</td>
<td class="product_name">
Product Name is very long long long long long long long long long long long
</td>
<td class="product_data">
<span>02/08/2022</span>
</td>
<td class="product_price">
<span>Order Total</span>
</td>
<td class="product_status">
<span>Purchuased</span>
</td>
<td class="product_action">
Show
</td>
</tr>
</table>

Related

Hide scrollable element under a sticky element

I want to hide the second header when it goes under the first header on small resolution when it scroll, I realy don't know how to do it, I tried everything.
.horizontal-scroll-table > .row::-webkit-scrollbar {
display: none;
background-color: red;
width: 500px;
}
table thead th {
background-color: red;
color: white;
padding: 16px 24px;
}
table thead th:last-child {
border-radius: 0 50px 50px 0;
}
table thead th:first-child {
border-radius: 50px 0 0 50px;
position: sticky !important;
left: 0;
z-index: 999;
}
#media (max-width: 991px) {
.horizontal-scroll-table > .row {
overflow-x: scroll;
white-space: nowrap;
overflow-y: hidden;
}
.horizontal-scroll-table > .row > .col-md-12 {
display: inline-block;
float: none;
}
}
<div class="horizontal-scroll-table">
<div class="row" style="text-align: -webkit-center;">
<table>
<thead class="" style="background-color: #111A40;">
<tr>
<th>Sticky header</th>
<th>header</th>
<th>header</th>
<th>header</th>
</tr>
</thead>
</table>
</div>
</div>
here it's an example try to scroll on small size
An interesting use case. I would have completely different approach; would this work for you?
header > div {
display: inline-block;
border: 1px solid red;
width: 120px;
}
header {
white-space: nowrap;
}
/* actual solution */
header > div:nth-of-type(1) {
background: lightpink;
position: sticky;
left: 0;
}
<header>
<div>Sticky</div>
<div>Child1</div>
<div>Child2</div>
<div>Child3</div>
<div>Child4</div>
<div>Child5</div>
<div>Child6</div>
<div>Child7</div>
</header>

Make Arbitrary Table Column Width Equal to Space Available

The scenario is I want a table column to consume all of the available with -- nothing more and nothing less. This is similar to using table td:last-child{width:100%} except the column many not be the last.
My sample code below demonstrates what I have so far.
The first table shows the result when the data fits comfortably.
The second table shows what happens when the column whose width I want to vary has too much data. What it does is it pushes the last column over. What I want it to do is to have a width still equal to the available space after accounting for the other columns and for the excess text to be treated as overflow, which means it should be hidden.
Please note that in the real-life scenario the table can be resized, so any solution that relies on setting the columns width to a value or percentage will probably not suffice.
Thanks in advance for any assistance.
<style>
.container {
position: relative;
width: 500px;
height: 200px;
display: inline-block;
font: 16px arial;
border: 1px solid steelblue;
background-color: lightgoldenrodyellow;
}
.variCell {
text-align: left;
width: 100%;
overflow: hidden;
white-space: nowrap;
}
.orderCell {
display: inline-block;
width: 65px;
text-align: right;
}
table {
position: absolute;
display: block;
margin-right: 10px;
border: none;
overflow: hidden;
width: 100%;
height: 100%;
cursor: pointer;
}
thead {
position: relative;
display: table-header-group;
height: 25px;
max-height: 25px;
background-color: #93aed2;
text-align: center;
font-size: 14px;
line-height: 25px;
white-space: nowrap;
}
tbody {
position: relative;
border: none;
overflow: hidden;
max-width: 100%;
max-height: 100%;
cursor: pointer;
}
</style>
<div class="container">
<table>
<thead>
<tr>
<td class="orderCell">
Col 1
</td>
<td class="variCell">
Col 2
</td>
<td class="orderCell">
Col 3
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="orderCell">
1
</td>
<td class="variCell">
Please use available space only.
</td>
<td class="orderCell">
100
</td>
</tr>
</tbody>
</table>
</div>
<div class="container">
<table>
<thead>
<tr>
<td class="orderCell">
Col 1
</td>
<td class="variCell">
Col 2
</td>
<td class="orderCell">
Col 3
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="orderCell">
1
</td>
<td class="variCell">
Please use available space only. Do not push the next column out of the table.
</td>
<td class="orderCell">
100
</td>
</tr>
</tbody>
</table>
</div>
I would suggest using table-layout:fixed for the table and white-space: break-word; for fixed columns and stop table from expanding.
.container {
position: relative;
width: 500px;
height: 200px;
font: 16px arial;
border: 1px solid steelblue;
background-color: lightgoldenrodyellow;
}
.variCell {
position: relative;
text-align: left;
width: 100%;
overflow: hidden;
white-space: nowrap;
}
.variCell span {
position: absolute;
top: 0;
left: 0;
right: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.orderCell {
display: inline-block;
width: 65px;
text-align: right;
}
table {
position: absolute;
display: block;
margin-right: 10px;
border: none;
overflow: hidden;
width: 100%;
height: 100%;
cursor: pointer;
}
thead {
position: relative;
display: table-header-group;
height: 25px;
max-height: 25px;
background-color: #93aed2;
text-align: center;
font-size: 14px;
line-height: 25px;
white-space: nowrap;
}
tbody {
position: relative;
border: none;
overflow: hidden;
max-width: 100%;
max-height: 100%;
cursor: pointer;
}
<div class="container">
<table>
<thead>
<tr>
<td class="orderCell">
Col 1
</td>
<td class="variCell">
Col 2
</td>
<td class="orderCell">
Col 3
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="orderCell">
1
</td>
<td class="variCell">
<span>Please use available space only. Do not push the next column out of the table.</span>
</td>
<td class="orderCell">
100
</td>
</tr>
</tbody>
</table>
</div>

Table: Minimize column width (multiple colspans)

I have this:
and want this (second column using less space):
Is there a way without introducing absolute values or fixed columns? I don't mind any other hacks like wrappers or invisible columns as long as the content sizes dynamically.
HTML
table {
border-collapse: collapse;
height: 100%;
background-color: blue;
white-space: nowrap;
}
.wrapper {
width: 40%;
font-family: avenir;
height: 100vh;
}
td > div {
color: white;
background-color: darkblue;
padding: 5px;
display: inline-block;
}
td {
padding: 0px;
border: 1px dotted white;
}
.w1px {
width: 1px;
}
.h-100 {
height: 100%;
}
<div class="wrapper">
<table>
<tr>
<td class="w1px"><div>Item1</div></td>
<td><div>Item2</div></td>
<td><div>Item3</div></td>
</tr>
<tr>
<td colspan="3"><div>Item Spanning All Three Above</div></td>
</tr>
<tr>
<td colspan="2"><div>Item Spanning Two</div></td>
</tr>
<tr class="h-100">
</tr>
</table>
</div>

multiple tables with the same TD width

To format these 2 tables I have a css sheet. The top table is a filter/sort selection. The second is a scrollable data table.
div#scrollTableContainer {
width: auto;
margin: 20px; /* just for presentation purposes */
border: 1px solid black;
}
#tHeadContainer {
background: #CC3600;
color: black;
font-weight: bold;
}
#tBodyContainer {
height: 750px;
overflow-y: scroll;
}
td:first-child {
min-width: 5%; /* EDIT */
max-width: 5%;
border-left:0;
}
td:first-child + td {
min-width: 4%;
max-width: 4%;
}
td:first-child + td + td {
min-width: 4%;
max-width: 4%;
}
<div id="scrollTableContainer">
<div id="tHeadContainer">
<table border="1" align="center" width="100%" cellpadding="0" cellspacing="0">
<tr>
<th bgcolor="<%=bgc0%>">USED</th>
<th bgcolor="<%=bgc0%>">STATUS</th>
</tr>
</table>
</div>
<div id="tBodyContainer">
<table border="1" align="center" id="tBody" class="TableData">
<td> stuff </td>
<td> More stuff </td>
</table>
</div>
</div>
Neither of the 2 tables are aligning column wise so that the Title/Header columns do not match the tables columns below. It also shows almost the same in chrome/IE, but firefox is a complete shamble.
Im at a loss to get this right guys, any help will be appreciated.
div#scrollTableContainer {
width: auto;
margin: 20px;
/* just for presentation purposes */
}
#tHeadContainer {
background: #CC3600;
color: black;
font-weight: bold;
}
#tBodyContainer {
height: 750px;
}
th:first-child, td:first-child {
min-width: 15%;
max-width: 15%;
width: 15%;
}
td:first-child+td {
min-width: 4%;
max-width: 4%;
}
td:first-child+td+td {
min-width: 4%;
max-width: 4%;
}
<div id="scrollTableContainer">
<div id="tHeadContainer">
<table border="1" align="center" width="100%" cellpadding="0" cellspacing="0">
<tr>
<th bgcolor="<%=bgc0%>">USED</th>
<th bgcolor="<%=bgc0%>">STATUS</th>
</tr>
</table>
</div>
<div id="tBodyContainer">
<table border="1" align="center" width="100%" cellpadding="0" cellspacing="0">
<td> stuff </td>
<td> More stuff </td>
</table>
</div>
</div>
You want to align the columns of both table vertically right?
If that is so, I have a solution for you
I have changed your css and u missed tr in second table.
https://jsfiddle.net/9ccwkoav/
div#scrollTableContainer {
width: auto;
margin: 20px; /* just for presentation purposes */
border: 1px solid black;
}
#tHeadContainer {
background: #CC3600;
color: black;
font-weight: bold;
}
#tHeadContainer th{
width:50%;
}
#tBodyContainer {
height: 750px;
overflow-y: auto;
}
.TableData{
width:100%;
}
.TableData td{
width:50%;
}
This should do the trick. Notice that there will be a little margin because of the scroll bar of the second table, but you can easily change it by adding a tab in the first array with the width of the scrollbar. Hope it will help
#scrollTableContainer {
width : 96%;
margin : auto;
border : 1px solid #ccc;
}
#tHeadContainer {
background-color : green;
width : 100%;
}
#tBodyContainer {
width : 100%;
height : 750px;
overflow-y : scroll;
}
#tHeadContainer table, #tBodyContainer table {
border-collapse : collapse;
width : 100%;
}
td, th {
border : 1px solid black;
}
tr {
width : 100%;
}
th:first-child, td:first-child {
min-width : 15%;
max-width : 15%;
width : 15%; /* Tweak this value to change the first column width */
}
<div id="scrollTableContainer">
<div id="tHeadContainer">
<table>
<tr>
<th>USED</th>
<th>STATUS</th>
</tr>
</table>
</div>
<div id="tBodyContainer">
<table>
<tr>
<td>Stuff</td>
<td>Some other stuff</td>
</tr>
</table>
</div>
</div>

CSS - setting table column height percentage changes row height

I have the following HTML and CSS:
table {
border-collapse: collapse;
}
table.patients,
table.patients > tr {
width: 100%;
}
table.patients td,
table.patients th {
border: 1px solid black;
}
table.patients_patient_table tr,
table.patients_patient_table td {
border: 1px solid red;
}
.patients_appointment {
text-align: left;
width: 25%;
}
.patients_patient {
text-align: left;
width: 25%;
padding: 0px;
}
.patients_patientID {
text-align: left;
width: 15%;
}
.patients_sex {
text-align: left;
width: 10%;
}
.patients_physician {
text-align: left;
width: 25%;
}
.patients_row {
height: 4em;
}
.patients_patient_table {
width: 100%;
height: 100%;
}
body {
font-family: verdana, sans-serif;
margin: 0;
padding: 0;
}
<table class="patients">
<tr class="patients_row">
<td class="patients_appointment">12/20/2014 7:00am</td>
<td class="patients_patient">
<table class="patients_patient_table">
<tr>
<td>Smith, John</td>
<td>55 Y</td>
</tr>
<tr>
<td colspan=2>test</td>
</tr>
</table>
</td>
<td class="patients_patientID">5678</td>
<td class="patients_sex">M</td>
<td class="patients_physician">Dr. John Smith</td>
</tr>
</table>
The results is the following table:
If I change the CSS for .patients_patient to this:
.patients_patient {
text-align: left;
width: 25%;
height: 100%;
padding: 0px;
}
table {
border-collapse: collapse;
}
table.patients,
table.patients > tr {
width: 100%;
}
table.patients td,
table.patients th {
border: 1px solid black;
}
table.patients_patient_table tr,
table.patients_patient_table td {
border: 1px solid red;
}
.patients_appointment {
text-align: left;
width: 25%;
}
.patients_patient {
text-align: left;
width: 25%;
height: 100%;
padding: 0px;
}
.patients_patientID {
text-align: left;
width: 15%;
}
.patients_sex {
text-align: left;
width: 10%;
}
.patients_physician {
text-align: left;
width: 25%;
}
.patients_row {
height: 4em;
}
.patients_patient_table {
width: 100%;
height: 100%;
}
body {
font-family: verdana, sans-serif;
margin: 0;
padding: 0;
}
<table class="patients">
<tr class="patients_row">
<td class="patients_appointment">12/20/2014 7:00am</td>
<td class="patients_patient">
<table class="patients_patient_table">
<tr>
<td>Smith, John</td>
<td>55 Y</td>
</tr>
<tr>
<td colspan=2>test</td>
</tr>
</table>
</td>
<td class="patients_patientID">5678</td>
<td class="patients_sex">M</td>
<td class="patients_physician">Dr. John Smith</td>
</tr>
</table>
Then the height of the outer table row changes:
Why does this happen? What I really want is the result to look like this:
Edit: I am testing this on Chrome.
Your first code uses
td.patients_patient {
height: auto; /* default value */
}
td.patients_patient > table.patients_patient_table {
height: 100%;
}
According to Table height algorithms,
The height of a table is given by the 'height' property for the
'table' or 'inline-table' element.
However, there is a problem, because the height is a percentage:
The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the value
computes to 'auto'.
A way to solve that issue is specifying an explicit height for td.patients_patient, as you did in your second code:
td.patients_patient {
height: 100%;
}
td.patients_patient > table.patients_patient_table {
height: 100%;
}
However, now there is another problem:
CSS 2.1 does not define how the height of table cells and table rows
is calculated when their height is specified using percentage values.
So you can't use a percentage. But don't worry:
The height of a 'table-row' element's box is calculated once the user
agent has all the cells in the row available: it is the maximum of the
row's computed 'height', the computed 'height' of each cell
in the row, and the minimum height (MIN) required by the cells.
Therefore, you can use any value not greater than the row's computed height, the computed height of other cells, and the minimum height required by the cells. Using greater values would also work, but the height of the row would be increased.
For example, you can use
.patients_patient {
height: 0;
}
table {
border-collapse: collapse;
}
table.patients,
table.patients > tr {
width: 100%;
}
table.patients td,
table.patients th {
border: 1px solid black;
}
table.patients_patient_table tr,
table.patients_patient_table td {
border: 1px solid red;
}
.patients_appointment {
text-align: left;
width: 25%;
}
.patients_patient {
text-align: left;
width: 25%;
height: 0;
padding: 0px;
}
.patients_patientID {
text-align: left;
width: 15%;
}
.patients_sex {
text-align: left;
width: 10%;
}
.patients_physician {
text-align: left;
width: 25%;
}
.patients_row {
height: 4em;
}
.patients_patient_table {
width: 100%;
height: 100%;
}
body {
font-family: verdana, sans-serif;
margin: 0;
padding: 0;
}
<table class="patients">
<tr class="patients_row">
<td class="patients_appointment">12/20/2014 7:00am</td>
<td class="patients_patient">
<table class="patients_patient_table">
<tr>
<td>Smith, John</td>
<td>55 Y</td>
</tr>
<tr>
<td colspan=2>test</td>
</tr>
</table>
</td>
<td class="patients_patientID">5678</td>
<td class="patients_sex">M</td>
<td class="patients_physician">Dr. John Smith</td>
</tr>
</table>