CSS display table-caption causes vertical layout - html

#container {
width: 960px;
height: 960px;
background-color: #ccc;
}
.box {
width: 300px;
height: 300px;
background-color: blue;
display: table-caption;
border: 0;
}
<div id='container'>
<span class='box'>Content</span>
<span class='box'>Content</span>
<span class='box'>Content</span>
<span class='box'>Content</span>
</div>
Table Caption Fiddle Demo
Now when I change table-caption to table-cell it renders horizontally. Below is the demo of it.
Table Cell Fiddle Demo
Any reason for the different renderings?

Here is what the spec says about display: table-caption:
table-caption (In HTML: CAPTION)
Specifies a caption for the table. All elements with 'display: table-caption' must be rendered, as described in section 17.4.
And here is what the section 17.4 says about rendering of caption boxes:
The caption boxes are block-level boxes that retain their own content, padding, margin, and border areas, and are rendered as normal block boxes inside the table wrapper box.
The key part is that they are rendered as normal block boxes and hence each of them is displayed one below the other (as in, in their own row).
Other points to note: (A summary of my discussion with GCyrillus in comments)
Parent container with display: table is not required for a child to have display: table-cell or display: table-caption. You can find more details and reference to the relevant part of the spec in this SO thread
There should ideally be only one caption per table. User Agents probably don't expect multiple captions to be provided under the same parent/table and it probably explains why Firefox renders it differently from Chrome. But details on that are beyond the scope of this answer (in my opinion) as the question only asks why display: table-caption causes vertical layout.
I concur with GCyrillus, it is definitely bad practice to use display: table-caption on multiple elements under the same parent. I believe you were doing trial and error in an attempt to learn.

.header{
writing-mode: vertical-rl;
padding-top: 30%;
font-weight: bold;
padding-right: 5px
}
table,tr,td{
border:1px solid black;
border-collapse: collapse;
padding: 5px;
}
<h1>Right Caption </h1>
<table>
<tr>
<td>
<table>
<tr> <th>SrNo.</th> <th>Name</th> <th>Department</th> </tr>
<tr>
<td>1</td>
<td>Natasha</td>
<td>IT</td>
</tr>
<tr>
<td>1</td>
<td>Umar</td>
<td>IT</td>
</tr>
<tr>
<td>1</td>
<td>Usman</td>
<td>BBA</td>
</tr>
<tr>
<td>1</td>
<td>Warda</td>
<td>BBA</td>
</tr>
</table>
</td>
<td rowspan="5" ><span class="header">Student Data</span> </td>
</tr>
</table>
<h1>Left Caption </h1>
<table>
<tr>
<td rowspan="5" ><span class="header">Student Data</span> </td>
<td>
<table>
<tr> <th>SrNo.</th> <th>Name</th> <th>Department</th> </tr>
<tr>
<td>1</td>
<td>Natasha</td>
<td>IT</td>
</tr>
<tr>
<td>1</td>
<td>Umar</td>
<td>IT</td>
</tr>
<tr>
<td>1</td>
<td>Usman</td>
<td>BBA</td>
</tr>
<tr>
<td>1</td>
<td>Warda</td>
<td>BBA</td>
</tr>
</table>
</td>
</tr>
</table>

Related

How to align html table td elements on the opposite (right) end of the screen

I have an image on the upper left of the screen but want to position some text on the evenly opposite side (upper right). But this code positions the subsequent td elements only slightly to the right and a bit lower. Do I need to add an align to the <td> elements?
<table>
<tr>
<td><img src="some_img" style='width:50%; height:50%;' />
<td style="vertical-align:bottom;">t1</td>
</tr>
<tr>
<td></td>
<td>t2</td>
</tr>
<tr>
<td></td>
<td>t3</td>
</tr>
</table>
One closing td is missing, other than that you can use the text-align css property to align the items inside the cell.
If I understand correctly, you may want something like this:
.cell{
width: 50vw;
background: #ccc;
text-align: right;
}
.image{
width:50%;
height:50%;
text-align: left;
}
<table>
<tr>
<td class="cell image"><img src="some_img"/></td>
<td class="cell">t1</td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell">t2</td>
</tr>
<tr>
<td class="cell"></td>
<td class="cell">t3</td>
</tr>
</table>

How to make CSS table-cell contents fill the height of the cell?

I have a div table layout like this:
...but I'd like the nested table on the right to match the height of the table on the left, so that the right table rows are equally spaced apart. It seems that there's some padding going on that's preventing the right table from filling the full height of it's container.
Want I want is this (it's a photoshop mock, but you get the idea):
I do not want to set a fixed height on the outer container. Both left and right table heights should match whichever one is tallest. I'm using a div table solution at the moment to contain the tables because it solves the problem whereby the table containers (light-green) height will match (I'm open to other possible solutions). However, it still leaves the problem of the shorter table not filling the height of it's container, as in the image.
Here's a fiddle.
The HTML:
<div class="outer-container">
<div class="inner-container">
<div class="child">
<table>
<tr>
<td>Label 1a</td>
<td>Value 1a</td>
</tr>
<tr>
<td>Label 1b</td>
<td>Value 1b</td>
</tr>
<tr>
<td>Label 1c</td>
<td>Value 1c</td>
</tr>
<tr>
<td>Label 1d</td>
<td>Value 1d</td>
</tr>
<tr>
<td>Label 1e</td>
<td>Value 1e</td>
</tr>
</table>
</div>
<div class="spacer"></div>
<div class="child">
<table>
<tr>
<td>Label 2a</td>
<td>Value 2a</td>
</tr>
<tr>
<td>Label 2b</td>
<td>Value 2b</td>
</tr>
<tr>
<td>Label 2c</td>
<td>Label 2c</td>
</tr>
</table>
</div>
</div>
</div>
and the styling:
.outer-container {
display: table;
padding: 10px;
background: #5f5f5f;
width: 400px;
margin-left: auto;
margin-right: auto;
}
.inner-container {
display: table-row;
padding: 10px;
margin-top: 50px;
width: 100%;
}
.child {
display: table-cell;
background: #d3e4d1;
border: 1px solid white;
}
.spacer {
display: table-cell;
width: 10%;
}
.child table {
width: 100%;
height: 100%;
padding: 10px;
}
.child td {
width: 50%;
}
.child td:first-child {
text-align: right;
padding-right: 10px;
}
IE8 and up solution required.
The table-cell contents were filling up the height of the cells, the tables (and table cells) were just different sizes because the contents were different and they weren't declared to be the same height.
Here's a very minimal working example: https://jsfiddle.net/egzs1sm3/
If you'd like you could remove the divs they're nested in and just apply the static height to the tables, I don't see why not.
Here's how to accomplish it via flexbox:
https://jsfiddle.net/tqvqsd2y/1/
display:flex on the container is inconsequential, that's just to make to make them be right next to eachother for comparison's sake. No reason you couldn't use that though, I think it's what you wanted.
Me again.
Do they have to be separate tables? Because two cells in the same table would automatically adjust the height and justify the content...
<table>
<tbody>
<tr>
<td>
<h3>
<span>asdf 1</span>
<span>asdf 2</span>
</h3>
<h3>
<span>asdf 1</span>
<span>asdf 2</span>
</h3>
</td>
<td>
<h3>
<span>asdf 1</span>
<span>asdf 2</span>
</h3>
<h3>
<span>asdf 1</span>
<span>asdf 2</span>
</h3>
<h3>
<span>asdf 1</span>
<span>asdf 2</span>
</h3>
</td>
</tr>
</tbody>
</table>
https://jsfiddle.net/7w963q7v/
Notice how different labels are now inline elements within block elements.
I have changed your existing HTML, that will work on IE8 too. Though I didn't tested on it, but I am sure, it won't deviate.
Option 1:
Using a cellspacing on the main table.
Please find the structure below:
<div class="outer-container">
<div class="inner-container">
<table cellspacing="15">
<tbody>
<tr>
<td class="child">
<table>
<!-- put your contents of the first table -->
</table>
</td>
<td class="child">
<table>
<!-- put your contents of the second table -->
</table>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Watch the demo here.
Option 2:
Without using the cellspacing.
<div class="outer-container">
<div class="inner-container">
<table> <!-- no 'cellspacing' here -->
<tbody>
<tr>
<td class="child">
<table>
<!--put your contents of the first table -->
</table>
</td>
<td class="spacer"></td> <!-- class spacer with 'width: 10%' -->
<td class="child">
<table>
<!--put your contents of the second table -->
</table>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Watch the demo here.
Update 1:
See the updated demo:
I don't think, the height of the nested table would be able to occupy the height of the largest table using only CSS. That's why I have made their parents as td, where it fills up the containers and doesn't depends upon the content size of its elements only, but the largest one out of all its siblings td's.
Anyways, one can always target the child elements of any other elements using either JS or CSS.

100% height in a td, positioning the text in the vertical middle

I am currently using EvoPDF (HTML to PDF) to build up a report in C#.
In this report we have a table, looking something like this in the fiddle:
http://jsfiddle.net/bk48srw1/3/
with the important part:
<tr>
<td>label for something</td>
<td style="position:relative;" rowspan="99999">
<div id="absolute">
<div class="centerd">
<span>value for all</span>
</div>
</div>
</td>
</tr>
The idea is that there are a variety of products, but they will have the same value in the second column, hence:
rowspan="99999"
The client wants the styling (border and background) to span the height of the second column, with the text in the middle. I have tried the position absolute, display:table, as well as vertical-align.
I cannot use a solution like Vertically align text in a span with fixed width and height
because I have no idea what the height would be (there could be an arbitrary number of tr's)
How do I make the div 100% height of the td, with the text displaying in the middle?
My preference is not to use JS, seeing that this code doesn't see a browser at all.
For styling purposes, I need to have about 3px padding inbetween the td and the div, seeing that I cannot add cellspacing to only 1 td.
Used to this change your html as like this
td{
width:50%;vertical-align:middle;
}
<table style="width:100% ">
<tr>
<td>
<table>
<tr><td>label for something</td></tr>
<tr>
<td>label for this:</td>
</tr>
<tr>
<td>label for this:</td>
</tr>
<tr>
<td>label for this:</td>
</tr>
<tr>
<td>label for this:</td>
</tr>
</table>
</td>
<td style="background:yellow; border: 1px solid black;text-align:center;">
<table width="100%">
<tr><td>value for all</td></tr>
</table>
</td>
</tr>
</table>
Here you go: http://jsfiddle.net/sjncndvn/2/
HTML markup:
<table style="width:100% ">
<tr>
<td>label for something</td>
<td style="position:relative;" rowspan="99999">
<div id="absolute">
<div class="centerd">
<span>value for all</span>
</div>
</div>
</td>
</tr>
<tr>
<td>label for this:</td>
<td></td>
</tr>
<tr>
<td>label for this:</td>
<td></td>
</tr>
<tr>
<td>label for this:</td>
<td></td>
</tr>
<tr>
<td>label for this:</td>
<td></td>
</tr>
</table>
CSS:
td{
width:50%;
display:table-cell ;
vertical-align:middle ;
}
#absolute {
width:100%;
background:yellow;
display:table;
border: 1px solid black;
}
.centerd {
display:table-cell;
vertical-align:middle;
text-align:center;
background-color:#pink;
}
Since #absolute no longer uses absolute positioning, you may want to change the ID name to something else.

Adjusting table cell width

Let's take 4 table columns - ID, Text, Date, Action. In my case table have always constant width - in example 960px.
How can I create such table as :
*-*------------------------------------*----------*----*
|1| Some text... |May 2011 |Edit|
*-*------------------------------------*----------*----*
|2| Another text... |April 2011|Edit|
*-*------------------------------------*----------*----*
As we can see, ID, Date and Action adjust their width to content, Text is as long as possible....
Is that possible to do without setting specific width of columns ? When ID = 123 or Date = November 2011, columns should automatically be wider...
Using a 100% width on the wide td and a fixed width for the table along with white-space:nowrap, this can be done:
Demo
HTML
<table>
<tr>
<td>1</td>
<td width="100%">Some text... </td>
<td>May 2011</td>
<td>Edit</td>
</tr>
<tr>
<td>2</td>
<td width="100%">Another text... </td>
<td>April 2011</td>
<td>Edit</td>
</tr>
</table>
CSS
table
{
...
width:960px;
}
td
{
...
white-space:nowrap;
}
basically, it's just like this: http://jsfiddle.net/49W5A/ - you have to set the cell-width to something small (like 1px) to make them stay as small as possible.
but as you'll see, theres one problem with the date-fields doing a line-wrap. to prevent this, just add white-space: nowrap; for your text-field: http://jsfiddle.net/ZXu7U/
working example:
<style type="text/css">
.table{
width:500px;
border: 1px solid #ccc;
}
.table td{
border: 1px solid #ccc;
}
.id, .date, .action{
width:1px;
}
.date{
white-space: nowrap;
}
</style>
<table class="table">
<tr>
<td class="id">1</td>
<td class="text">Some Text...</td>
<td class="date">May 2011</td>
<td class="action">Edit</td>
</tr>
<tr>
<td class="id">2</td>
<td class="text">Another Text...</td>
<td class="date">April 2011</td>
<td class="action">Edit</td>
</tr>
</table>
My best advice to you is to not touch the widths of the table, the table automatically layouts in a way that does all cells best.
However, if you'd like to push through, I'd use width: 1px; on the cells that needs adjusting (one of each column is enough). Also use white-space: nowrap on all cells. that will make sure the lines don't break.
Try this:
.id, .date, .action is the table cells (td).
CSS:
.id, .date, .action {
width: 1em;
}
It worked for me.
The width:1em will not cut the text but force the width size to the minimum.
The best way that I've found for setting table column widths is to use a table head (which can be empty) and apply relative widths for each table head cell. The widths of all cells in the table body will conform to the width of their column head. Example:
HTML
<table>
<thead>
<tr>
<th width="5%"></th>
<th width="70%"></th>
<th width="15%"></th>
<th width="10%"></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Some text...</td>
<td>May 2018</td>
<td>Edit</td>
</tr>
<tr>
<td>2</td>
<td>Another text...</td>
<td>April 2018</td>
<td>Edit</td>
</tr>
</tbody>
</table>
CSS
table {
width: 600px;
border-collapse: collapse;
}
td {
border: 1px solid #999999;
}
View Result
Alternatively, you can use colgroup as suggested here.

How can I vertically align a <table> in the middle of a fixed height <div>?

Why does the code below not cause the <table> to be vertically-aligned in the middle of the <div>?
<div style="width: 850px; height: 470px;vertical-align: middle;" align="center">
<table style="padding-left: 20px; width: 700px; border: 10px groove #0033CC; background-color: #F9F9F9;">
<tr>
<td>
</td>
<td>
</td>
<td>
</td>
</tr> <tr>
<td>
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
</div>
I want the <table> in the middle of the <div>, but it is at the top! How can I fix this?
Thanks for your future advice.
Outside of table cells, vertical-align sets the vertical alignment of text within a line, rather than the vertical alignment of entire elements like your table.
However, if you set display: table-cell; on your <div>, that seems to achieve the effect you want.
I’m not sure how many browsers support this though. I’ve checked in Chrome 6, Firefox 2 and Opera 10.5, and they’re fine with it. Internet Explorer could be a different matter.
Have you tried "display:flex;"?
div{
width: 850px;
height: 470px;
display: flex;
/* WIDTH and HEIGHT are required */
justify-content: center;
align-items: center;
}
td, table{
border-collapse: collapse;
border: 1px solid black;
}
<div>
<table>
<tr>
<td>Lorem</td>
<td>Lorem</td>
<td>Lorem</td>
</tr>
<tr>
<td>2019</td>
<td>2018</td>
<td>2017</td>
</tr>
</table>
</div>
Try this:
<body style="vertical-align:middle">
<table style="display:inline-block">
<!-- your stuff -->
</table>
</body>
table is a block element. To get it to vertically align, I think it needs to be displayed as inline. inline-block will often give you the best of both worlds in situations like these. Cheers!
Its easy. Always use this >> style="vertical-align:middle" << inside every TD. You can use top, middle and bottom. You can push it in the CSS too.
try this:
#centerAligned{
text-align: center;
margin-top: 50%;
}
it worked for me!!