How to implement a comment structure like stackoverflow - html

Here is the scenario: I want exactly something like stackoverflow's comments. A table contained 3 <td>. one for the number of votes, one for shapes (vote up and flag), one for text of comment. So each <td> has its own property:
VN (Votes Number): If the number not exist, then width = 0;, also the with of this cell should be dynamic. (for every-digit number)
S (Shapes): This cell has fixed width, it should be noted that the visibility of its shapes is hidden in first and they will be show on hover of <tr>, then the width of this cell always should be assigned.
CT (Comment Text): The width of this cell should be all the remaining width. It should be word-wrap: break-word;.
The structure:
+--+-+---------------------------------------------------+
|VN|S|CT |
+--+-+---------------------------------------------------+
example1:
+-+-+---------------------------------------------------+
|4|^|this comment is a test...! |
+-+-+---------------------------------------------------+
example2:
+-+------------------------------------------------------+
|^|this comment has not any voteup ...! |
+-+------------------------------------------------------+
example3:
+---+-+---------------------------------------------------+
|123|^|the width of number of vote up cell should be |
| | |changeable and it should be noted that this cell is|
| | |break-word. |
+---+-+---------------------------------------------------+
Here is my try: But it does not work correctly.
HTML:
<div class="container">
<table>
<tr>
<td class="VN">4</td>
<td class="S">^</td>
<td class="CT">this is a sample.</td>
</tr>
</table>
</div>
CSS:
.container{
width: 60%;
}
table{
table-layout: fixed;
width: 100%;
}
td{
word-wrap: break-word;
vertical-align: top;
}
.VN{
width: auto;
}
.S{
width: 10px;
}
.CT{
width: 98%;
}
As I said, I don't know why my code does not work correctly (It should be noted my container is responsive), How can I fix it ?
Here is a fiddle of what I did.

Your code is correct but when user try to type "sssssssssssssssssssssssssssss" this will count as one word, so you need to add Hyphenation to your CSS code for recognition of long text since you have word-break: break-word;. https://jsfiddle.net/q7o6m2ka/2/
.CT {
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
padding: 5px;
width: 98%;
}

here is a demo you can do it jsfiddle
<div class="container">
<table>
<tr>
<td>
<table>
<tbody>
<tr>
<td><span>1</span></td>
<td><a>^</a>
</td>
</tr>
</tbody>
</table>
</td>
<td>
<div>
<span>text of the comment</span>
</div>
</td>
</tr>
</table>
</div>

With only this CSS your table works:
http://jsfiddle.net/1485tLf2/1
.container{
width: 600px;
}
.S, .VN{
width: 2%;
}
You don't need the other things. Tables fits automatically with content if you don't specifiy width. To avoid movements of elements and all comments will be symetric, only specify the small columns width. If the votes column needs more space, the table shrinks automatically to fix it without problems
EDIT
In order to complete the code with your comments, here you are new css and fiddle:
.container{
width: 60%;
}
td{
vertical-align: top;
border: 1px solid;
}
td.CT {
word-break: break-all;
}
.S, .VN{
width: 2%;
}
td:empty {
visibility:hidden;
}
See it working: https://jsfiddle.net/rubhxdm1/11/

Related

How did the browser decide on the widths of these table columns?

I have the following table:
I'm a little unhappy with it, because the width of the second column forces the text to wrap into 3 lines. Wouldn't it have made more sense for the renderer to give the first column a little less width, and wrap both elements onto two lines? Like this:
Is there some way I've set my table up wrongly?
(I don't want to set an explicit column width because I'm not sure what other content I might want to put in there later. I'd like to work with the browser's default behaviour as much as possible).
Thank you!
<table class="sequence">
<tbody>
<tr>
<td>Rhythm</td>
<td>Msec</td>
</tr>
<tr>
<td>8xxooxxoo 6xxxxxx 8xxooxxoo 6xxxxxx</td>
<td>168ms average<br>(5 tapbacks)</td>
</tr>
</tbody>
</table>
and css
table.sequence {
margin-left:auto;
margin-right:auto;
width: 320px;
}
table.sequence th, table.sequence td {
border: 1px solid black;
border-collapse: collapse;
padding-left: 5px;
padding-right: 5px;
padding-top: 2px;
padding-bottom: 2px;
vertical-align: middle;
word-wrap: normal;
}

aligning the table row in HTML

My problem is that I can't find a way to fix the table row height,
if the username exceeded it overlaps to the other column.
check the last two row
and it's also scrollable at side and the username is still in their position.
code for single row:
<tr>
<td class="headcol">
<div class="innerHead">
<div class="user-id" style="display:none;">18993</div>
<input type="checkbox" class="checkboxes" name="user_select[]">
TestingalksdjaskldjsalkdjalskdjaksduqwoieuoqweuowqeiTesting#gmail.com </div>
</td>
<td class="forcedWidthUserCode">Tested091237871</td>
<td class="textAlignCenter">Field staff</td>
<td class="forcedWidth">Testing</td>
<td class="forcedWidth">Tested</td>
<td> N/A </td>
<td class="textAlignCenter">Active</td>
<td> N/A </td>
<td class="forcedWidth"> N/A </td>
<td> N/A </td>
<!--<td>N/A</td>-->
</tr>
CSS:
.headcol {
position: absolute;
width: 18em;
border-right: 2px solid #fff;
background-color: #fff;
z-index: 0;
}
table tr td {
/* background: #fff; */
padding: 6px;
text-align: left;
vertical-align: middle;
border-bottom: 1px solid #ddd;
}
how can I align and wrap the text base on the width of the username column?
It happens because there is a white space between those nodes (the checkbox and the text node). The line breaks at white space.
There are two way to handle this.
As mentioned by #Supraja Ganji: Use word-break.
table tr td {
word-break: break-all;
}
or prevent the whole line from breaking, and hide anything that overflows:
table tr td {
white-space: nowrap;
overflow: hidden;
}
Your username is too long and doesnot contain any space, so it is not wrapping.
for td give word-break: break-all
table tr td {
/* background: #fff; */
padding: 6px;
text-align: left;
vertical-align: middle;
border-bottom: 1px solid #ddd;
word-break: break-all;
}
Using a div inside td is a very bad idea.
Using a div instide a td is not worse than any other way of using tables for layout. (Some people never use tables for layout though, and I happen to be one of them.)
If you use a div in a td you will however get in a situation where it might be hard to predict how the elements will be sized. The default for a div is to determine its width from its parent, and the default for a table cell is to determine its size depending on the size of its content.
The rules for how a div should be sized is well defined in the standards, but the rules for how a td should be sized is not as well defined, so different browsers use slightly different algorithms.
Let me know if you require any further help
.headcol {
position: relative;
width: 18em;
border-right: 2px solid #fff;
background-color: #fff;
z-index: 0;
}
.innerHead {
word-break: break-all;
overflow: hidden;
}
<table>
<tbody><tr>
<td class="headcol">
<div class="innerHead">
<div class="user-id" style="display:none;">18993</div>
<input type="checkbox" class="checkboxes" name="user_select[]">
TestingalksdjaskldjsalkdjalskdjaksduqwoieuoqweuowqeiTesting#gmail.com </div>
</td>
<td class="forcedWidthUserCode">Tested091237871</td>
<td class="textAlignCenter">Field staff</td>
<td class="forcedWidth">Testing</td>
<td class="forcedWidth">Tested</td>
<td> N/A </td>
<td class="textAlignCenter">Active</td>
<td> N/A </td>
<td class="forcedWidth"> N/A </td>
<td> N/A </td>
<!--<td>N/A</td>-->
</tr>
</tbody></table>

The elements of my page are not sized/aligned as I want them to be

The fiddle for my code is here:
http://jsfiddle.net/wasingej/k2GPw/
I think the problem has something to do with how I specify right/left aligned divs but I'm not sure:
div.right
{
float:right;
margin-right: 2%;
border-style:solid;
}
As you can see, the fiddle produces a jumbled mess of garbage. My goal was to have the page look similar to this:
https://i.imgur.com/DVyk7s6.png
I'm fairly new to css so I'm guessing that my problem is caused by something fairly obvious. Any ideas?
Okay here's a very simple example of doing this with a table. This data appears to be tabular in nature, so while there are wonks who insist a table is NEVER okay, using a table for tabular data is appropriate.
HTML:
<table>
<thead>
<tr>
<th colspan=2>List 1 Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>Owner 1 Name:</td>
<td>Owner 1 Status</td>
</tr>
<tr>
<td>Owner 2 Name:</td>
<td>Owner 2 Status</td>
</tr>
<tr>
<td>Owner 3 Name:</td>
<td>Owner 3 Status</td>
</tr>
</tbody>
</table>
CSS:
table {
border: 1px solid;
width: 50%;
padding: 2%;
border-radius: 6px;
}
td {
border: 1px solid;
padding: 1% 2%;
}
td:first-child {
text-align: right;
}
thead th {
text-align: center;
}
The fiddle: http://jsfiddle.net/BUp82/
Your issues are stemming from two things... proper handling of floats and overflows
This forked fiddle should show you your expected results: JSFIDDLE
The main bit of css that you need to add is this:
div.outer
{
//... your existing css ...
overflow: hidden;
}
I also added a 100% wide DIV around the title areas like this:
div.title { width: 100%; overflow: hidden; text-align: center; }
*my fiddle has min-height and min-width set for demonstration purposes

Align table-cell using css

I need to reduce the whitespace between Name: and the "Bob",similary between Age: and "20".
How can I accomplish using css.
fiddle:
http://jsfiddle.net/QfN3f/2/
html:
<table class="table">
<tr class="table-row">
<td class="table-col">Name:</td>
<td class="table-col">Bob</td>
<td class="table-col">Age:</td>
<td class="table-col">20</td>
</tr>
</table>
css:
.table {
width:100%
}
I'd add a class to your "labels"
<table class="table">
<tr class="table-row">
<td class="table-col label">Name:</td>
<td class="table-col">Bob</td>
<td class="table-col label">Age:</td>
<td class="table-col">20</td>
</tr>
</table>
CSS
.table {
width:100%
}
.label {width:50px; font-weight:bold;}
http://jsfiddle.net/QfN3f/5/
You could also use n-th child.
tr td:nth-child(odd) {width:50px; font-weight:bold;}
http://jsfiddle.net/QfN3f/6/
I would also re-consider the appropriatness of a table here as it may not actually be tabular data. Maybe consider a definition list.
If you must use a table for this, I'd suggest (assuming that your label td elements are always the odd-numbered elements):
td:nth-child(odd) {
text-align: right;
}
td:nth-child(even) {
text-align: left;
}
JS Fiddle demo.
But, I'd strongly suggest moving to more semantic HTML, such as a definition list:
<dl>
<dt>Name</dt>
<dd>Bob</dd>
<dt>Age</dt>
<dd>20</dd>
</dl>
With the CSS:
dt, dd {
display: inline-block; /* allows the elements to be side-by-side */
width: 5em;
margin: 0; /* removes the default margins */
padding: 0.2em 0; /* aesthetics, but sets/overrides the defaults */
}
dt {
text-align: right; /* to move the 'label' towards the 'value' */
}
dd {
text-align: left;
text-indent: 0.5em; /* aesthetic, gives a small separation; adjust to taste */
}
JS Fiddle demo.
The gaps are so wide because table cells will expand to take up as much space as is available. To reduce the whitespace, stop stretching the table all the way across the parent div. Simply remove width:100% from the table.
Of course, you may want to simultaneously add a min-width to the cells, so that the columns don't get too close together.
Add a % or fixed width to the column:
<td class="table-col" width="20px">Name:</td>
or
HTML
<td class="table-col name-col">Name:</td>
CSS
.name-col{
width:20px;
}
If no width per column is specific the columns width is the same for each one.
If you want to reduce to the gaps space you may also want to reduce the table width by removing width:100% and writing a fixed width or smaller one or writing a fixed width to all the columns.
Jsfiddle
You can remove width:100% and specify padding for table cells (td).
.table td {
padding: 10px
}
jsfiddle
Also if you want to customize some individual cells you can add different class to some <td class="myCustomClass"> and assign different width/padding or whatever property you want in css.
Use this html code:
<table class="table">
<tr class="table-row">
<td class="table-col-a">Name:</td>
<td class="table-col-b">Bob</td>
<td class="table-col-a">Age:</td>
<td class="table-col-b">20</td>
</tr>
</table>
And this css code:
.table-col-a{float:right;}
Also you can use paddings to make it exactly as you want.
See working jsFiddle demo
Simply modify your HTML to:
<table class="table">
<tr class="table-row">
<td class="table-cola">Name:</td>
<td class="table-colb">Bob</td>
<td class="table-cola">Age:</td>
<td class="table-colb">20</td>
</tr>
</table>
and your CSS to:
.table
{
width:100%
}
.table td
{
width: 25%;
}
.table-cola
{
text-align: right;
}
.table-colb
{
text-align: left;
}
that will yield:

Make link in table cell fill the entire row height

I have a table of data and each cell is a link. I want to allow the user to click anywhere in the table cell and have them follow the link. Sometimes the table cells are more than one line but not always. I use td a {display: block} to get the link to cover most of the cell. When there is one cell in a row that is two lines and the others are only one line the one liners don't fill the entire vertical space of the table row. Here is the sample HTML and you can see it in action here http://www.jsfiddle.net/RXHuE/:
<head>
<style type="text/css">
td {width: 200px}
td a {display: block; height:100%; width:100%;}
td a:hover {background-color: yellow;}
</style>
<title></title>
</head>
<body>
<table>
<tbody>
<tr>
<td>
<a href="http://www.google.com/">Cell 1<br>
second line</a>
</td>
<td>
Cell 2
</td>
<td>
Cell 3
</td>
<td>
Cell 4
</td>
</tr>
</tbody>
</table>
</body>
Set an arbitrarily large negative margin and equal padding on the block element and overflow hidden on the parent.
td {
overflow: hidden;
}
td a {
display: block;
margin: -10em;
padding: 10em;
}
http://jsfiddle.net/RXHuE/213/
You need a small change in your CSS. Making td height:100%; works for IE 8 and FF 3.6, but it doesn't work for Chrome.
td {
width: 200px;
border: solid 1px green;
height: 100%
}
td a {
display: block;
height:100%;
width:100%;
}
But making height to 50px works for Chrome in addition to IE and FF
td {
width: 200px;
border: solid 1px green;
height: 50px
}
td a {
display: block;
height:100%;
width:100%;
}
Edit:
You have given the solution yourself in another post here; which is to use display: inline-block;.
This works when combined with my solution for Chrome, FF3.6, IE8
td {
width: 200px;
border: solid 1px green;
height: 100%}
td a {
display: inline-block;
height:100%;
width:100%;
}
Update
The following code is working for me in IE8, FF3.6 and chrome.
CSS
td {
width: 200px;
border: solid 1px green;
height: 100%;
}
td a {
display: inline-block;
height:100%;
width:100%;
}
td a:hover {
background-color: yellow;
}
HTML
<table>
<tbody>
<tr>
<td>
<a href="http://www.google.com/">Cell 1<br>
second line</a>
</td>
<td>
Cell 2
</td>
<td>
Cell 3
</td>
<td>
Cell 4
</td>
</tr>
</tbody>
</table>
The example lays here
Little late to the party, but there's a nice solution I just discovered.
You can use a combination of relative and absolute positioned elements, along with a pseudo element to get the effect you're looking for. No extra markup needed!
Change the table cell (<td>), to be position: relative;, and create a ::before or ::after pseudo element on the <a> tag, and set it to position: absolute;, and also use top: 0; left: 0; right: 0; bottom: 0;.
Because the pseudo element is attached to the anchor tag, and you're telling it to take up the entire table cell, it will force the anchor tag to be at least that size, whilst not affecting the actual content of the anchor tag itself (thereby retaining its vertically centered alignment).
For example
table {
border-collapse: collapse;
table-layout: fixed;
}
td {
position: relative;
width: 200px;
padding: 0.5em 1em;
border: 2px solid red;
background-color: lime;
}
td a {
/* FONT STYLES HERE */
text-decoration: none;
}
td a::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
<table>
<tbody>
<tr>
<td>
<a href="http://www.google.com/">Cell 1<br>
second line</a>
</td>
<td>
Cell 2
</td>
<td>
Cell 3
</td>
<td>
Cell 4
</td>
</tr>
<tr>
<td>
Cell 5
</td>
<td>
<a href="http://www.google.com/">Cell 6<br>
second line</a>
</td>
</tr>
</tbody>
</table>
Hope this helps!
Following hack works [Tested on Chrome / Firefox / Safari]
Have the same padding for td and anchor elements. And for anchor also have margin which is equal to -ve of padding value.
HTML
<table>
<tr>
<td><a>Hello</a></td>
</tr>
</table>
CSS:
td {
background-color: yellow;
padding: 10px;
}
a {
cursor:pointer;
display:block;
padding: 10px;
margin: -10px;
}
Working Fiddle :http://jsfiddle.net/JasYz/
Try display: block:
td a {display: block; height:100%;}
[EDIT] WTF ... I can confirm this doesn't work in FF 4 and Chrome. This works:
td a {display: block; height: 2.5em; border: 1px solid red;}
That suggests that height:100%; isn't defined in a table cell. Maybe this is because the cell gets its size from the content (so the content can't say "tell me your size" because that would lead to a loop). It doesn't even work if you set a height for the cells like so:
td {width: 200px; height: 3em; padding: 0px}
Again the code above will fail. So my suggestion is to use a defined height for the links (you can omit the width; that is 100% by default for block elements).
[EDIT2] I've clicked through a hundred examples at http://www.cssplay.co.uk/menus/ but none of them mix single line and multi-line cells. Seems like you hit a blind spot.
I will post the same answer here, as I did on my own question.
Inspired by Jannis M's answer, I did the following:
$(document).ready(function(){
$('table tr').each(function(){
var $row = $(this);
var height = $row.height();
$row.find('a').css('height', height).append(' ');
});
});
I added a since empty links (not containing text nodes) can not be styled(?).
See my updated fiddle.
Only problem here is that using display: block forces the browser to ignore the vertical align: center...
oops.
I jury rigged it to look right for one cell with height:60 and a font that occupied 20 pixels by adding a br... Then I realized that I had some items with 2-line text. Dang.
I ended up using the javascript. The javascript doesn't give the nice mousey pointy clicker thing, but the line of text does, so it will actually trigger a visual response, just not where I want it to... Then the Javascript will catch all the clicks that 'miss' the actual href.
Maybe not the most elegant solution, but it works well enough for now.
Now if I could only figure out how to do this the right way....
Any ideas on how to add the mouse icon change to a hand for the area covered by the onclick? Right now, the click to page works, but the icon only changes when it hits the href which only affects the text.
Why don't you just get rid of the <a> altogheter and add an onClick to the <td> directly?
<head>
<style type="text/css">
td {
text-align:center;
}
td:hover {
cursor:pointer;
color:#F00;
}
</style>
<title></title>
</head>
<body>
<table>
<tbody>
<tr>
<td onclick="location.href='http://www.google.com/';">Cell 1<br />second line</td>
<td onclick="location.href='http://www.google.com/';">Cell 2</a></td>
<td onclick="location.href='http://www.google.com/';">Cell 3</td>
<td onclick="location.href='www.google.com';">Cell 4</td>
</tr>
</tbody>
</table>
This way you cut out the middle man.
PS: i know this was asked and answered many years ago, but none of the answers above solved the problem in my case. Hope this helps someone.
For me the only solution is to replace <table> <tr> with <div>s and style them using display:table and display:table-row accordingly.
Then you can replace <td> with just <a> and style it with display:table-cell.
Work perfectly even on varying heights of <td> contents.
so original html without anchors:
<table>
<tr>
<td>content1<br>another_line</td>
<td>content2</td>
</tr>
</table>
now becomes:
a:hover
{
background-color:#ccc;
}
<div style="display:table; width:100%">
<div style="display:table-row">
content1<br>another_line
content2
</div>
</div>
I have used this solution: works better then the rest in my case.
CSS:
.blocktd {width: 100%; height: 100%; padding: 0px; overflow: hidden}
a.blocktd {margin: 0em; padding: 50px 20px 50px 20px; display: block;}
a.blocktd:hover {border: 4px solid #70AEE8; border-radius: 10px; padding: 46px 16px 46px 16px; transition: 0.2s;}
And in HTML: ...