Table cell break word won't shrink - html

I often use this HTML/CSS structure to create a mobile-friendly table (It changes layout on narrow (mobile) screens; something very lacking in CSS frameworks) and it has been quite reliable for me. In my main project I have several tables with lots of data and varying widths.
If you open this codepen and change the view to 'debug' you can shrink the page width. Past 500px the table layout will change. The thead is hidden, secondary labels are shown and the tds are set to display: flex. (I like to use the responsive device toolbar in the inspector).
Under the table is a more simple set of divs, that behaves the way I want the divs inside the TD to work, but for some reason, the second div inside the td stops shrinking at a certain point. I have tried different combinations of word-wrap and white space but so far no luck. Seems the difference has to do with these divs being inside a table...
Is this just a limitation of tables or is there a way I can make the right div shrink like the second example?
Thanks!
https://codepen.io/sinrise/pen/qoypYJ
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>number</th>
<th>content</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="td-label">number</div>
<div>this is the first one</div>
</td>
<td>
<div class="td-label">number</div>
<div>this is the second one</div>
</td>
</tr>
</tbody>
</table>
<div class="cont">
<div class="in1">oneoneone oneone one oneoneoneoneoneon</div>
<div class="in2">two two twotwotwo twotwotwotwo</div>
</div>
table { width: 100%; table-layout: fixed; margin: 0 0 10px; }
th { padding: 10px 10px 0; text-align: left; }
td { padding: 10px; border: 1px solid #ccc; }
.td-label {
display: none;
min-width: 100px;
max-width: 100px;
font-weight: bold;
}
#media(max-width: 500px) {
thead { display: none; }
td {
display: flex;
margin: 0 0 10px;
> div:not(.td-label) {
word-wrap: break-word;
min-width: 1px;
}
}
.td-label {
display: table;
}
}
.cont {
display: flex;
border: 1px solid black;
> div {
&:first-of-type {
min-width: 100px;
max-width: 50px;
}
min-width: 1px;
border: 1px solid #aaa;
word-wrap: break-word;
}
}

The trick is to set the table width to 100%, add a min-width to the second div, and set display: table on the second div. I updated the pen and code above to reflect.

Related

Resize HTML column and resize whole table to match div

I got a div serving as a header and below it a table that acts as a post, with a title, body and one cell and/or colums that hass arrows and a counter for upvotes and downvotes.
First problem I have is alignment and second resizing colums
Here is my code
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
table {
table-layout: fixed;
margin: 0 auto;
width: 50%;
}
#votes {
text-align: center;
}
div {
font-size: 25px;
margin: auto;
color: white;
background-color: black;
padding: 15px;
width: 50% ;
border-radius: 12px;
}
<div>RANDOM THINGS</div>
<table>
<tr>
<th id="title">Title</th>
<th id="votes" rowspan="3">
<img src='images/arrow_up.png' onclick='Upvote()'/>
<br>0<br>
<img src='images/arrow_down.png' onclick='Downvote()'/>
</th>
</tr>
<tr id="textBody">
<td rowspan="2">Text Body</td>
</tr>
<tr>
</tr>
</table>
What I got so far
You need to add box-sizing: border-box; to the div so it doesn't expand it's width in order to add the padding.
If using border-box the width and height properties (and min/max properties) includes content, padding and border.
Your css would end up as:
div {
font-size: 25px;
margin: auto;
color: white;
background-color: black;
padding: 15px;
width: 50% ;
border-radius: 12px;
box-sizing: border-box;
}
The rest of it unchanged. Here you have a CodePen showcasing it: https://codepen.io/javierojeda/pen/LqpLVN
However, as #hungerstar mention... You wouldn't use a table for that kind of things. You may want to use the new display: grid, display: flex or even use 3 divs and some CSS to accommodate them as you need.
For more info:
https://www.w3schools.com/cssref/css3_pr_box-sizing.asp
https://www.w3schools.com/css/css_grid.asp
https://www.w3schools.com/css/css3_flexbox.asp

Fixed height of table row in html

I have a table hosted in a div. Neither the table nor the hosting div has a height specified.
After the table header row, each subsequent row looks like this:
<tr class="movie-info-row">
<td>
<div class="movie-cover">
<img class="movie-image" src="" />
<a class="movie-link" href="" target="_blank">IMDb</a>
</div>
</td>
<td colspan=5>
<div class="movie-details">
<p class="movie-file"></p>
<div class="movie-div-left">
<p class="movie-category"></p>
<p class="movie-director"></p>
<p class="movie-insertdate"></p>
</div>
<div class="movie-description-container">
<p class="movie-description"></p>
</div>
</div>
</td>
</tr>
I want each table row (except for the header) to have the same fixed height but I just can't get it to work after hours of trying all kinds of approaches (and of course searching on stackoverflow and elsewhere).
My css (in less syntax) looks like this:
.movie-info-row {
height: 240px;
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
height: 100%;
overflow: hidden;
}
}
.movie-cover {
border: 1px solid black;
width: 130px;
height: 100%;
overflow: hidden;
}
.movie-details {
border: 1px solid black;
height: 100%;
overflow: hidden;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
float: left;
width: 40%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
float: right;
width: 60%;
overflow: hidden;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
As you can see I have fixed the height of the row to 240px and for good measure have each td height set to 100% with overflow hidden.
The trouble maker is the description text, which can be quite long and it messes with the table row height. As you can see I have set overflow to hidden in many places (which is probably overkill).
Note: This is not browser specific. I am not even using IE. I am testing it with firefox and chrome (both latest versions).
I am really at a loss. What am I doing wrong? Any help would be greatly appreciated.
ETA:
Here's a picture of a table row as it looks now: SampleRow
As you can see the description text takes the row height with it. I want it limited to a fixed height - basically the hight of the title image. And yes, I want all the information (with more to come) in there. So that is non-negotiable.
Too many hiddens and floats and whatnot. Simplify and conquer. Also you have nested selectors inside of another selector (p{} and td{})
Demo Fiddle
CSS:
.movie-info-row {
height: 240px;
}
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
border: 1px solid black;
height: 100%;
}
div, p {
display: table-cell;
}
.movie-cover {
width: 130px;
overflow: hidden;
}
.movie-details {
height: 100%;
width: 100%;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
width: 35%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
width: 55%;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
By the looks of your HTML all of your data will go into one table cell is this how you want it?
Why not structure it like using individual tags for the headers with a colspan of what ever and then do a new for each row you need along with its data like this?
<tr>
<th colspan=2>Header</th>
</tr>
<tr>
<td>cell 1 data</td>
<td>cell 2 data</td>
<tr>
Then you can do this in the css, which would give you this same fixed height for all the rows:
tr {
height: 240px;
}
That way you can just use the table headers to describe each column and use a lot less code to make it work properly. Or from what I understand you are trying to do.

Responsive table design by cell

I have this table with three cells in the first row. I'm trying to create a design that will bring down the last cell if there is no space. So something like 2 on top, 1 below. And as the window gets even small 1 on each row. I'm having trouble finding anything like this.
I was able to get a responsive design to stack all cells on top of each other depending on size but if I could find a better solution that would be nicer.
HTML:
<table id="dashboard" cellpadding="0" cellspacing="0">
<tr>
<td id="TopLeft"><div class='chartLoadingOverlay'>Loading chart please be patient...</div></td>
<td id="TopRight"><div class='chartLoadingOverlay'>Loading chart please be patient...</div></td>
<td id="BottomLeft"><div class='chartLoadingOverlay'>Loading chart please be patient...</div></td>
</tr>
</table>
CSS:
#dashboard{
border-collapse: separate;
border-spacing: 5px 5px;
border: 5px solid red;
background-color: blue;
}
div.chartLoadingOverlay{
font-style:italic;
color:gray;
border:1px silver solid;
background-color:#F5F5F5;
line-height:250px;
height:250px;
width:500px;
text-align:center;
margin:2px;
}
#media only screen and (max-width: 1000px){
/* Force table to not be like tables anymore */
#dashboard table{
width: 100%;
border-collapse: collapse;
border-spacing: 0;
display: block;
position: relative;
width: 100%;
}
#dashboard tbody {
/*display: block;*/
width: auto; position: relative;
overflow-x: auto;
white-space: nowrap;
}
#dashboard tbody tr {
display: inline-block;
vertical-align: top;
}
#dashboard td {
display: block;
}
}
That's not possible. But even if it were doable, a more elegant solution would be to stack 3 divs side-by-side and responsively put them one below the other. Check this Bootstrap example for something quite similar to what you want.
Tables should not be used for responsive design...
Store this to make it a thumb rule : http://shouldiusetablesforlayout.com/
You can try something like this to make DIV structure and make that responsive:
<div id="container">
<div id="col_left"> something here</div>
<div id="col_mid"> something here </div>
<div id="col_mid"> something here</div>
<div style="clear: both"></div>
</div>
CSS:
#container
{
width: 100 %;
clear: both;
border: 1px solid #CCC;
}
#col_left
{
float: left;
width: 20%;
margin: 0 5px 0 0;
border: 1px solid #CCC;
}
#col_mid
{
float: left;
width: 20%
margin: 0 5px 0 0;
border: 1px solid #CCC;
}
#col_right
{
float: right;
width; 35%;
margin: 5px;
border: 1px solid #CCC;
}
you can refer this http://jsfiddle.net/aasthatuteja/awvck/
You can change display like this http://jsfiddle.net/Yr22s/1/
BUT, it effectively changes your table to be div
sorry i dont think this is possible ..actually its not posiible...you cant break a tabular design...
what does a row mean???its a collection of cells...so one row will always contain a particular number of cells...you cant change number of cells in a row depending on screen width..its fixed...
for example consider this table in image
now if your screen width gets too small to accommodate its total width then it will overflow horizontally and horizontal scroll bar will be introduced...and if one cell gets too tall then row size will take the height of tallest cell and rest of the cell will be aligned vertically middle by default...you cant change this property dynamically depending on screen size
what you can do is ..define there width using %..so it wil grow or shrink according to screen width...
this is one reason(actually there are many) why you should avoid tabular design..use container(<div>) to design your website

Why does increasing padding in this <a> increase the vertical margin?

This is probably the most unusual CSS behavior I have ever seen:
I have an extremely simple table that consists of two cells - one with plain text and another with a link:
<div class="content">
<table>
<tr>
<td>
Hello, world!
</td>
<td>
Hello, world!
</td>
</tr>
</table>
</div>
I have also applied the following CSS to the table:
div.content {
background-color: green;
height: 100px;
}
table td {
background-color: red;
height: 50px;
}
table td a {
background-color: orange;
box-sizing: border-box;
display: block;
height: 100%;
padding: 8px;
width: 100%;
}
When rendered in Chrome 28, I see the following:
Why is there a large amount of red above and below the link? I have specified height: 100%; for the link, so it should be taking up the full height of the <td>, which has an explicit height.
It's definitely an issue with the box-sizing:border-box attribute. My guess is that putting that inside a table cell (which is treated differently then a div) is confusing the browser. Often, new techniques + old techniques don't mix.
I would suggest doing the following:
table td a {
background-color: orange;
display: block;
height: 100%;
padding: 8px;
}
The width:100% was unneeded since the table cell already expanded to the text width + padding width. For some reason, it doesn't seem to add the padding to the height 100% with the table cell (go figure, weirdness with tables! lol). If you need it to expand to a larger table cell width, I would suggest then putting the width:100% back but then ditch the horizontal padding (i.e. put padding:8px 0px;).
As far as I think its the box-sizing attribute causing this, change your css to:
table td a {
background-color: black;
height: 100%;
display:block;
margin: 0;
padding: 0px;
width: 100%;
padding-top: 12px;
}
Hope that helps;
Add This Code to table td:
display:inline-block;
because There is some difference between tables and divisions in box modeling.
you must set display-block on any none-block element for apply box-model style.
Try setting height in px for a as
table td a {
background-color: orange;
box-sizing: border-box;
display: block;
height: 50px;
padding: 8px;
width: 100%;
}
here's an example of a jury-rig: http://jsfiddle.net/rTAwd/
We're using a line height to adjust the cell's height, so we don't need to mess with vertical alignment, and relying on a wrapper div to provide our background and padding.
<div class="content">
<table>
<tr>
<td>Hello, world!</td>
<td>
<div> Hello, world!</div>
</td>
</tr>
</table>
</div>
css
div.content {
background-color: green;
height: 100px;
}
table td {
background-color: red;
}
table td div a {
line-height: 2em;
}
table td div {
background-color: orange;
padding: 8px;
}
I think its a bug, i had the same issue a while ago, if you want the text to vertically align in the middle, instead of using display:block on the <a> tag use display:table and use border-spacing instead of padding, like this:
table td a {
background-color: orange;
display: table;
height: 100%;
border-spacing: 8px 13px;
}
I removed the width:100% too since it will do it by default, you can see an example here.
border-spacing is the CSS property for cellpadding.

css - stretched and evenly spaced horizontal menu

I hope, you can help me, I have a horizontal menu, my problem is the following:
The first is normal stretch with table, the second is what I want: stretch + even gaps between texts.
I achieved this with additional non breaking spaces, but it works only by fixed menu widths, so if I change the menu width I have to change the count of the nbsp characters. Is there any way to do this with css, and without those non breaking spaces?
The count of the menupoints and the menu width can change, so I need an automatical solution without javascript. No settings by individual columns, unless you can give me an algorithm which I can run on server side.
I don't think this is possible with css only, but I'm not a css guru, that's why I asked....
<style>
* {
margin: 0px;
padding: 0px;
font-size: 16px;
}
table {
width: 400px;
}
td {
border: 1px solid blue;
text-align: center;
}
</style>
<table>
<tr>
<td>aa</td>
<td>aaaaaaaaaaaaa</td>
<td>aaaaaaaaa</td>
</tr>
</table>
<table>
<tr>
<td> aa </td>
<td> aaaaaaaaaaaaa </td>
<td> aaaaaaaaa </td>
</tr>
</table>
Not sure of all the parameters here ("stretch" is not very clear), but wouldn't some left and right padding on the links do it? Because this is a menu, I won't use a table but a <ul> instead. There are plenty of variations on this if it's not what you want:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
ul, li {margin: 0; padding: 0;}
ul {list-style: none; display: table; border-spacing: 5px; }
li {display: table-cell; background: #f7f7f7; border: 1px solid blue; }
li a {padding: 0 30px;}
</style>
</head>
<body>
<ul>
<li>aa</li>
<li>aaaaaaaaaaaaa</li>
<li>aaaaaaaaa</li>
</ul>
</body>
</html>
Edit: The below answer does not work well with Internet Explorer versions as recent as IE 11. Its algorithm for cell sizing appears to work differently than other browsers.
While this will require some cross-browser testing, here's what I've been using:
http://jsfiddle.net/aaronadams/j3cEQ/
HTML:
<p>Default spacing:</p>
<ul>
<li>aa</li>
<li>aaaa aaaa aaaa</li>
<li>aaa aaa aaa</li>
<li>aa aa</li>
</ul>
<p>Even spacing:</p>
<ul class="even">
<li>aa</li>
<li>aaaa aaaa aaaa</li>
<li>aaa aaa aaa</li>
<li>aa aa</li>
</ul>
CSS:
ul {
display: table;
margin: 0 auto;
padding: 0;
width: 100%;
max-width: 30em;
text-align: center;
}
li {
display: table-cell;
margin: 0;
padding: 0 0.125em;
white-space: nowrap;
}
.even li {
width: 1%;
}
So far, this is providing me with a menu that works really well across all screen sizes; on mobile it shrinks to screen width, on desktop it grows up to a certain size, and the links are always evenly spaced.
Credit here for the inspiration: https://stackoverflow.com/a/16509901/802414
You can set the width for the individual columns.
JSFiddle
HTML
<table>
<tr>
<td class="first">aa</td>
<td class="second">aaaaaaaaaaaaa</td>
<td class="third">aaaa aaaaaaaaaaaaa</td>
</tr>
</table>
CSS
table {
width: 400px;
}
td {
border: 1px solid #d3d3d3;
text-align: center;
}
.first {
width: 30%;
}
.second {
width: 45%;
}
.third {
width: 30%;
}
JSFIDDLE
You can set the "padding left and right for individual column
HTML
<table>
<tr>
<td class="first">aa</td>
<td class="second">aaaaaaaaaaaaa</td>
<td class="third">aaaa aaaaaaaaaaaaa</td>
</tr>
</table>
CSS
table { width: 400px; }
td { border: 1px solid #d3d3d3; text-align: center;}
.first { padding: 0 3em; }
.second { padding: 0 2em; }
.third { padding: 0 4em; }
This can be achieved with CSS by making the parent element text-align: justify, and the child elements display:inline-block; However, justified text only works properly when there's at least 2 lines. The pseudo :after element is used to force an extra (very tiny) line:
#container {
height: 125px;
text-align: justify;
border: 10px solid black;
font-size: 0.1px; /* IE 9/10 don't like font-size: 0; */
min-width: 600px;
}
#container div {
width: 150px;
height: 125px;
display: inline-block;
background: red;
}
#container:after {
content: '';
width: 100%; /* Ensures there are at least 2 lines of text, so justification works */
display: inline-block;
}
Credit to https://css-tricks.com/equidistant-objects-with-css/ for this technique.