Fixing overflow issues when the width of the column is unknown - javascript

I am working on displaying data from a database on a web page.
My problem is that some of the data is very long and does not contain spaces (think very long path names), so it overflows the table without wrapping.
Currently the widths of the columns are determined using table-layout:auto, because I am working with a lot of different databases and tables, so I do not want to hard code the widths.
Therefore, when I try and use overflow:wrap, it just breaks the other columns into one-letter-wide messes.
Here are some of my ideas (none of which I can get to work):
Use table-layout:auto to calculate the suggested widths, set the widths to be those values, and then set overflow:wrap.
Tell the browser to break at characters other than just spaces, i.e. '/'.
Only set overflow:wrap if a column is longer than a certain amount.
I am currently using CSS and a little bit of JavaScript.
Any other ideas?

You have to use:
max-width and overflow-x properties in your css
.table tr td {
max-width: 100px;
overflow-x: hidden;
border: 1px solid #ff0000;
}
<table class="table">
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
</tr>
<table>

Some simple solutions that come to mind:
Use ellipses with manually triggered expansion for lines > N chars
/a/really/long/file/name/that/is/really/just/too/l... [expand]
This can work when the data you're showing doesn't really need to be visible all the time, and the user can choose to view all of it if they are interested. With this one, you don't need to worry about what type of information each cell has.
Data-specific column widths
If you know the type of data that will appear in your columns, you can define a mapping to resize the widths of the columns.
This requires some extra work to get the column types and configure the mappings, and then resizing the columns.
{ dataTypeWidths: { default: 'auto', filename: '300px' } }

You can set a max-width combined with overflow-x: hidden and text-overflow: ellipsi, i think that will resolve your problem.
td {
max-width: 200px;
overflow-x: hidden;
text-overflow: ellipsis;
border: 1px solid black;
}
<table>
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit.Integertellusmassa,fringillaacquamnec,temporconguelectus.Sedimperdietaclacusidtempus.Sedutfelisaduiiaculistemporinasapien.Integervelliberomi.Morbiutenimsagittis,sollicitudinipsumin,ullamcorpersapien.Phasellusidfelisatligulatristiquehendrerit.Nuncsitametipsumidquamtinciduntfacilisis.Pellentesquehabitantmorbitristiquesenectusetnetusetmalesuadafamesacturpisegestas.Namsitametdictumeros.</td>
<td>Pellentesquefermentummattisleo,sedblandittortorhendreritnec.Vestibulumeuturpislacus.Fusceliberorisus,dignissimegetsodalesnon,dictuminsem.Quisqueblanditmiante,eutristiqueorciporttitorsitamet.Donecpretium,eratetaccumsanfringilla,velitjustotristiqueorci,sedfringillaquamrisusnonenim.Praesenthendreritmassaultriceseratmalesuadapretium.Aeneansitametnuncsodales,vehiculaeroseget,ornarelorem.Proinquisfermentumsapien,utvehiculafelis.Duisquiseleifendleo.Suspendisseinnequefringilla,tristiquelectuseu,fermentumdiam.Nuncmassalectus,aliquamidmassaeu,pretiumullamcorperlectus.Aliquamfeugiatexegetornaretincidunt.Donectristiqueeratseddiamvehiculaauctor.Proinorcijusto,consecteturegetcursusut,pellentesquevelleo.Nampulvinarrisusetnislfacilisisaliquam.</td>
<td>Inhachabitasseplateadictumst.Craspulvinarsuscipitfelis,ullamcorperpulvinarlorem.Vivamuspulvinarinterdumlibero.Maurisvenenatisaugueodio,aultriceserossuscipitvel.Donecutfelissitameteratconsecteturbibendumegetetnulla.VestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliaCurae;Crastempus,magnavelelementumlobortis,ipsummassaporttitorarcu,mollisvehiculaanteenimvitaelectus.Fuscemolliseumagnaapretium.Praesentegestasaugueanuncultricies,ataliquamodiodignissim.Insagittismaurisest,sedlacinialeoornareeu.VestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliaCurae;Namrisusaugue,gravidasedullamcorperin,feugiatetdolor.Maurisposuerenuncquam,necdignissimmassagravidatincidunt.Quisquesemperdiamlibero,intemporlectusullamcorperut.</td>
<td>Suspendissevenenatisaliquamsapientinciduntconsequat.Aliquamveldiamegetsapienvehiculadapibus.Namblanditamagnaquisiaculis.Orcivariusnatoquepenatibusetmagnisdisparturientmontes,nasceturridiculusmus.Orcivariusnatoquepenatibusetmagnisdisparturientmontes,nasceturridiculusmus.Quisquelacinianunclorem,ultriciesvolutpatduifinibusquis.Praesentmalesuada,odioeuconsequatgravida,nisllacussagittismagna,sitametultriciesquamtellusporttitorelit.Fusceduilorem,viverraquisipsumet,pulvinaraliquamaugue.Donecinterdumscelerisquequamidfaucibus.Sedmollistinciduntquam,ideleifenddiammaximusa.Sedvitaemagnanonlectushendreritlacinia.Donecvenenatisauguevitaepulvinarpulvinar.Etiamposuereapurusetplacerat.Pellentesquefinibusdictumimperdiet.Crascursusfelisvelpellentesquerutrum.</td>
</tr>
<table>

What about using the:
word-break: break-word;
this will keep the columns widths and will show all the data
.table tr td {
max-width: 100px;
overflow-x: hidden;
border: 1px solid #ff0000;
word-break: break-word;
}
<table class="table">
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
</tr>
<table>
Code snippet copied from #MrMins answer and updated.

Related

Pure CSS fixed table header?

I'm using Semantic UI for the CSS base. Here's a fiddle I've been working on.
I'm having trouble getting the existing answers working from googling around. They all seem to have this problem where there is a ton of whitespace to the right.
I'm trying to get it working such that it integrates nicely with the existing CSS of semantic UI to look good (no whitespace to the side), but I'm not having any luck and I've been at it for a while.
It's fine if this only works with newer browsers since I'll be using electron anyway.
This CSS looks like it's required but I'm not sure how to modify it to work properly with what I have:
tbody, thead tr { display: block; }
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
The source of the whitespace problem seems to be the ui class. It has several media queries on it that cause the content to re-flow at smaller screen sizes. If you look at the media query it doesn't apply if you add the class stackable to your table like below.
<table class="ui striped table unstackable">
Also, you only have 4 columns, seems like you want 5. Make the following change.
tbody td, thead th {
width: 140px !important;
}
thead th:last-child, tbody tr td:last-child{
width: 296px !important; /* 140px + 16px scrollbar width */
}
Working fiddle here

How to split <table> into multiple <div>?

I am working with a large amount of data table (many lines many columns). The solution that I chose to use is putting my table into a overflow:scoll div. I would like to be able to see the 1st row even when scrolling down.
Is it possible to do it in html ? Otherwise, is there any trick like js trick?
I'm assuming you want something like this?
https://jsfiddle.net/s07w38me/
No JavaScript really required. You can simply position: absolute the contents of a div inside each th.
e.g.
CSS
th div {
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
HTML
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<!-- ...etc... -->
PS: This could be done a lot better, but this example above is a fork based on an existing JSfiddle I found.
Check out jQuery.floatThead (demos available) which is very cool, can work with DataTables too, and can even work inside an overflow: auto container.
The first row that you want to remain visible should be position:fixed and to set it to the top of that div top:0. Now your other columns would be overlapped by the position:fixed one, so make sure you give your scrollable div a padding-top equal to the height of the fixed column

Html Table: Word Break AND Limit Td Height?

I am able to limit table cell (<td>) width - I just set the width, and set overflow to hidden. However, I am NOT able to limit table cell height and keep word wrap. If I remove word-wrap, the height stays consistent (nothing forces it, because text just continues horizontally and gets cut off). If I add word-wrap, it seems to ignore the height property and expands the cell vertically.
PLNKR
The goal is to set a fixed table width and height, and then have text wrap (break to next line when reaching horizontal end of cell), but to be cut off vertically when it reaches the bottom. My current styles are these:
<style>
table{
border: 1px solid;
table-layout: fixed;
border-collapse: collapse;
}
tr{
vertical-align: top;
}
td{
word-break:break-all;
width: 80px;
height: 40px;
border: 1px solid;
border-collapse: collapse;
overflow: hidden;
}
</style>
Edit: This is a bonus, but ideally, if an image was placed in a cell, that would get cut off both vertically and horizontally as well, but that's just a "nice to have" and not really part of the q.
Edit 2: Here is an inline-block solution, but it's undesirable, hence not posted as an answer: http://plnkr.co/edit/qvA1wzkEdcrsA2Y9qWdV?p=preview
Figured it out! (Except the answer it a little hokey and only works in CSS3). Using a psuedo after element, and a negative margin, we can trick the table cell into not expanding it's height:
td:after {
content: '';
display: block;
margin-bottom: -10000px;
}
Example plunker: http://plnkr.co/edit/frch27eCDoTBlDEVyUGB?p=preview
Edit:
It seems that -100% will stop the table cell from expanding equal to the height of the table. Thus -100% is not the optimal solution. We'll replace this with a extremely large negative pixel amount. This will fix very long sentences.
I am just posting the "basic"/obvious solution for anyone reading this post later. Put a div inside your table cell, and set width/height to the same size as the cell. Then set the div's overflow and overflow-y to hidden. You shouldn't have any problems with margins/padding/etc, but you can set them to zero if need be.
td{
word-break:break-all;
width: 80px;
height: 40px;
border: 1px solid;
border-collapse: collapse;
overflow: hidden;
background-color:yellow;
}
div{
background-color:cyan;
width: 80px;
height: 40px;
overflow: hidden;
overflow-y: hidden;
}

Automatically stretching elements to fit in parent container using css

I'm trying to make a vertical navigation bar inside a box with fixed height. How can I make the buttons dynamically change height equally to fit inside the box? Here's a jsfiddle to demonstrate what I mean.
http://jsfiddle.net/0w3f2fm1/
So now if I am to add a sixth or a seventh button, they will be evenly stretched to fit nav container. Is it possible to make it with css only, or should javascript/jquery intervene?
Note: They will be added using back-end php/mysql application, not by code.
Also note, that the height I currently have is done using padding because I want the text to be centered inside the button.
Thanks
The problem in you question is you have given parent height in fixed size and you want child elements to be stretched to fill the parent.
So you have to give the height of li in percentages.
about vertical centering of text you can use either display:table-cell, vertical-align:middle properties however using tables for layout is not a best practice.
So Im using positions to center align the text.
Here is the jsbin:
http://jsbin.com/jirozicifedo/2/
Here is the dynamic solution (Javascript):
http://jsbin.com/batuyoxupofu/1/edit
I recommend to use html + css instead of javascript.
And since the new function of SO isn't working yet, link here: http://codepen.io/anon/pen/pHhEo
Code here:
<style>
table {
width: 200px;
height: 400px;
}
table tr {
vertical-align: middle;
}
table tr td {
padding-left: 20px;
}
table tr td:hover {
background-color: #000;
color: #fff;
cursor: default;
}
</style>
<table>
<tr>
<td>Button 1</td>
</tr>
<tr>
<td>Button 2</td>
</tr>
<tr>
<td>Button 3</td>
</tr>
<tr>
<td>Button 4</td>
</tr>
<tr>
<td>Button 5</td>
</tr>
</table>
If you change the height, the button's height will also change automatically.
You could use Flex-box to achieve the basic idea of what you are describing:
http://css-tricks.com/snippets/css/a-guide-to-flexbox/
It's super-easy to center things (both direction) and it's really, well, flexible and also it has a ton of option as to how to distribute content.
The only draw-back is that it isn't great for compatibility with older browser. It's fairly well-supported for newer ones though (it is a strong canditate to be added as a standard), depends what exactly it is going to be used for....
Fast to learn too.
===========EDIT, see comments========
html:
<body>
<div class="container">
<div class="item">Button1</div>
<div class="item">Button2</div>
<div class="item">Button3</div>
<div class="item">Button4</div>
</div>
</body>
For CSS:
body {
height: 30em;
border: 2px solid #ff00ff;
}
.container {
height:100%;
width: 10em;
display: flex;
flex-direction: column;
justify-content:center;
}
.item {
flex-grow: 1;
flex-direction: column;
border: 2px solid black;
}
Borders just to show extent of the blocks, if you want to try it in a browser. I checked and seems all new browser (including IE) support this.
Oh, and other thing you might decide you want after all: They don't have to be of equal size, you can easily set proportions for them.
If you id="itemX" for each button, you can use the following to set any ratios you want:
#item1 {
flex-grow: 1;
}
#item2 {
flex-grow: 2;
}
#item3 {
flex-grow: 1;
}
So in that case, #item2 will use 2/4 of the available container (so in this case, the full height of the container), and the other ones 1/4 each...

Text truncation based on cell width

I need javascript solution for ellipsis text truncation.
There is a percentage table which can be re-sized according to the screen resolution. While re-sizing the screen, when the table cell reached 20px it should truncate the text inside it. Which means it should not decrease the width below 20px.
I have done this using css solution (ellipsis) but unfortunately it is not widely supported for all browsers So I am looking for pure java-script solution to truncate the text by calculating the cell width.
here is how I am using css for this
td{
background:#cccc33;
text-overflow: ellipsis;
white-space: nowrap;
width: auto;
max-width: 20px;
overflow: hidden;
}
DEMO

Categories