I am trying to make a web-page where I have a table of information and an image side-by-side as in the example below
Example:
bar fOo
Instead of:
bar
fOo
I have placed the image within a div and the information table in another div element, and I have been playing with the CSS properties to try to get them to be side-by-side, however they refuse to work as expected.
The CSS is below, #book is the image itself, while book_information is the information inside the table.
#book
{
float: right;
flex: 33.33%;
padding: 5px;
margin-left: 0;
width: 50%;
}
#book_information
{
width: 50%;
float: left;
padding-right: 0;
margin-right: 0;
}
table
{
border-collapse: collapse;
float:top;
border: 1px solid black;
table-layout: fixed;
width: 50%;
}
What should I use to allow this to work as expected? and what improvements could work I work on to get it responsive?
Below is the html structure of the page at the moment that I am using along with this:
<main>
<div>
<div class= "left" id="book"><img src="Book.jpg" alt="></div>
<div class="left" id="book_information">
<table id="information">
<tr>
<td class="1">Price:</td>
<td class="1">€18.90</td>
</tr>
<tr>
<td>Author</td>
<td></td>
</tr>
<tr>
<td class="1">About</td>
<td class="1"><p></p></td>
</tr>
<tr>
<td>Where to get it:</td>
<td>Amazon ,
Casa Del Libro ,
FNAC ,
Libelista
</td>
</tr>
</table>
</div>
</div>
</main>
There are different ways of doing this.
Here's a solution that involves using float:left style for your table:
table {
float: left;
}
img {
width: 100px;
height: 100px;
}
<table>
<tr>
<td>Price</td>
<td>$5</td>
</tr>
<tr>
<td>Author</td>
<td>Bob</td>
</tr>
</table>
<div>
<img
src="https://via.placeholder.com/120.png?text=Book+Image"
alt="Book Image Here">
</div>
This one involves putting your table and image in yet another table:
img {
width: 100px;
height: 100px;
}
<table>
<tr>
<td>
<table>
<tr>
<td>Price</td>
<td>$5</td>
</tr>
<tr>
<td>Author</td>
<td>Bob</td>
</tr>
</table>
</td>
<td>
<div>
<img
src="https://via.placeholder.com/120.png?text=Book+Image"
alt="Book Image Here">
</div>
</td>
</tr>
</table>
Given a table with a column that contains numbers, I'd like to position them in the center.
But, I'd like to right-align the numbers as well!
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: center;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</tbody>
</table>
Outputs:
Desired output:
Note: The table cell width should be constant (200px), regardless of the numbers. For example, if all numbers are 0, they all should be in the center of the table:
Also:
You are allowed to modify the content of the <td>s, but there should be one number per <tr>.
CSS only, please.
Updated based on an edit of the question and a few comments
In a comment you wrote "In the desired outcome, the cell width stays the same (200px) as numbers change".
In another comment you wrote "...my numbers are links and I want them to occupy the full cell width".
Given those requirements, the only CSS based solution I can find is, where one use CSS Table instead of <table> elements, an anchor a element displayed as table-row, making the full width clickable without adding an event handler, and for the centering, using pseudo elements to puch the numbers to the middle.
Stack snippet
.table {
display: table;
border: 1px solid black;
}
.tr {
display: table-row;
text-decoration: none;
color: black;
}
.tr span {
display: table-cell;
width: 200px;
}
a.tr {
text-align: right;
}
.tr::before, .tr::after {
content: '';
display: table-cell;
width: 50%;
}
<div class="table">
<div class="thead">
<span class="tr">
<span>Amount</span>
</span>
</div>
<div class="tbody">
<a href="#1" class="tr">
<span>45</span>
</a>
<a href="#2" class="tr">
<span>2</span>
</a>
<a href="#3" class="tr">
<span>18923538273</span>
</a>
<a href="#4" class="tr">
<span>9823</span>
</a>
</div>
</div>
<div class="table">
<div class="thead">
<span class="tr">
<span>Amount</span>
</span>
</div>
<div class="tbody">
<a href="#1" class="tr">
<span>0</span>
</a>
<a href="#2" class="tr">
<span>0</span>
</a>
<a href="#3" class="tr">
<span>0</span>
</a>
<a href="#4" class="tr">
<span>0</span>
</a>
</div>
</div>
_____________________________________________________________________________
This is my first answer, which I will leave, as there might be someone that can make use of it as is.
One simple way to accomplish that is to simply nest a table for the values, center it using auto margin and right align its td's content.
This way you will get pretty much the exact same behavior as with your original markup, but get a better control of the values alignment.
Stack snippet
table {
border: 1px solid black;
}
th {
width: 200px;
}
table table {
border: none;
margin: 0 auto;
}
table table td {
text-align: right;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<table>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<table>
<tr>
<td>0</td>
</tr>
<tr>
<td>0</td>
</tr>
<tr>
<td>0</td>
</tr>
<tr>
<td>0</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
You can of course use div's instead of a table, displayed as inline block or inline flex column.
Inline block
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: center;
}
td > div {
display: inline-block;
}
td > div > div {
text-align: right;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<div>45</div>
<div>2</div>
<div>18923538273</div>
<div>9823</div>
</div>
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<div>0</div>
<div>0</div>
<div>0</div>
<div>0</div>
</div>
</td>
</tr>
</tbody>
</table>
Inline flex column
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: center;
}
td > div {
display: inline-flex;
flex-direction: column;
}
td > div > div {
text-align: right;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<div>45</div>
<div>2</div>
<div>18923538273</div>
<div>9823</div>
</div>
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<div>0</div>
<div>0</div>
<div>0</div>
<div>0</div>
</div>
</td>
</tr>
</tbody>
</table>
TL;DR:
table {
border: 1px solid black;
width: 200px;
}
td {
text-align: right;
min-width: 10px;
}
td:first-child, td:last-child {
width: 50%;
}
... and adding an extra column before and after the existing one. jsFiddle here.
Initial answer:
Considering your markup,
td {
text-align: right;
border-left:7rem solid transparent;
border-right:7rem solid transparent;
}
... should do it.
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: right;
border-left:7rem solid transparent;
border-right:7rem solid transparent;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</tbody>
</table>
Any other solution involves changing the markup (you need to add inner elements inside <td>s, give them smaller width than the <td>, and right align their text). You can do it by modifying the HTML source or on the fly, using JavaScript.
After a good number of tries, the only reliable solution I found (implying markup modification and no JavaScript), was to add additional columns in the table, relying on the table's ability to line up all the cells in a column.
I updated the snippet below so that the column occupies the minimum necessary width, based on most wide number and right-aligns all cells based on resulting width width. This means that when all values are 0, the entire row of values are centered. Here it is:
table {
border: 1px solid black;
width: 200px;
}
td {
text-align: right;
min-width: 10px;
}
td:first-child, td:last-child {
width: 50%;
}
/* just stacking tables side by side, not part of solution */
table {
float: left;
width: 200px;
margin-right: 7px;
}
body { overflow-y: hidden;}
<table>
<thead>
<tr>
<th colspan="3">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>45</td>
<td></td>
</tr>
<tr>
<td></td><td>2</td><td></td>
</tr>
<tr>
<td></td><td>0</td><td></td>
</tr>
<tr>
<td></td><td>1234</td><td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="3">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>0</td>
<td></td>
</tr>
<tr>
<td></td><td>2</td><td></td>
</tr>
<tr>
<td></td><td>1</td><td></td>
</tr>
<tr>
<td></td><td>4</td><td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="3">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>44</td>
<td></td>
</tr>
<tr>
<td></td><td>0</td><td></td>
</tr>
<tr>
<td></td><td>1155</td><td></td>
</tr>
<tr>
<td></td><td>1234548775564</td><td></td>
</tr>
</tbody>
</table>
make text-align:right and padding-right:5emin td css selector
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: right;
padding-right: 4em;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</tbody>
</table>
<style>
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: center;
float:right; <!--added this-->
margin-right:50px; <!-- and this-->
}
</style>
I added float:right in td
adjust the margin-right value to your desired value;
One option is to change the display property for td elements to block
You can then set a max-width to bring td elements to the center of tr elements.
Once that's done you set the text-align property to right for td elements to make the numbers start from the right hand side.
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
display: block;
max-width: 70%;
text-align: right;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</tbody>
</table>
Wrap your numbers with element(span) inside the td and add the text align right styles on it.
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: center;
}
td span {
width: 150px;
text-align: right;
background: beige;
display: inline-block;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td><span>45</span></td>
</tr>
<tr>
<td><span>2</span></td>
</tr>
<tr>
<td><span>18923538273</span></td>
</tr>
<tr>
<td><span>9823</span></td>
</tr>
</tbody>
</table>
.table {
display: flex;
align-items: center;
justify-content: center;
width: 300px;
background-color: red;
flex-direction: column;
}
div {
text-align: right;
}
<body>
<div class='table'>
<div>
<div>1</div>
<div>1111111</div>
<div>1111111111111</div>
</div>
</div>
</body>
text-align :right ----> pulls the text into right end
padding-right: 50% or padding-left : 50% ----> add space from the right or left to center
use 45 - 49 percentage in padding to make a crisp center alignment depends on your requirement
table {
border: 1px solid black;
}
th {
width: 200px;
}
td {
text-align: right;
padding-right: 50%;
}
<table>
<thead>
<tr>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>18923538273</td>
</tr>
<tr>
<td>9823</td>
</tr>
</tbody>
</table>
#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>
I have two tables floated side by side in a parent div. The leftmost table has a margin-right of 10%. As you can see in the image, the margin is calculated correctly (in this case, the parent is 850px, and the metrics inspector shows an 85px margin) but when drawn, is incorrect (much smaller.)
Resizing the window to make it redraw immediately fixes it. What is going on here!?
HTML:
<table id="subscriptions" class="data">
<tr>
<th colspan="2">Subscriptions
<span id="remaining">Remaining</span></th>
<th></th>
</tr>
<tr>
<td>Spin Classes</td>
<td class="right">3</td>
<td class="right">Redeem</td>
</tr>
<tr>
<td>Spin Classes</td>
<td class="right">3</td>
<td class="right">Redeem</td>
</tr>
</table>
<table id="redeemed" class="data">
<tr>
<th>Redeemed Items</th>
<th class="right">Redeemed</th>
</tr>
<tr>
<td>Spin Class</td>
<td class="right">3/3/13</td>
</tr>
<tr>
<td>Spin Class</td>
<td class="right">3/3/13</td>
</tr>
</table>
CSS:
#subscriptions, #redeemed {
width: 45%;
float: left;
clear: both;
margin: 25px 10% 0 0;
}
#redeemed {
clear: none;
margin-right: 0;
}
I think if you get rid of both the clear lines in the css it might fix it?
I am trying to have a table with fixed column widths and horizontal scrolling when the width of the columns is greater than the containing block.
The only time the fixed column widths work is when the sum of column widths < containing block (i.e. no scroll)
Otherwise, the fixed column widths seem to get ignored. Anyone know how to do this? here's my html and css.
<div class="scroll-content-grid21">
<div class="ExtraScrollableContainerDiv">
<table class="regular" style="width:1440px">
<tr>
<th>Item #</th>
<th>Description</th>
<th>Rate</th>
<th>Qty</th>
<th>Price</th>
<th>Amount</th>
<th>Prev Qty</th>
<th>Prev Amt</th>
etc. more columns
</tr>
<%
for (int i = 0; i < this.Model.BusinessObject.Items.Count; i++)
{
%>
<tr>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotReferenceNumber %></td>
<td style="width:240px"><%: this.Model.BusinessObject.Items[i].SnapshotShortDescription%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotUnitRate%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotQuantity%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotUnitOfMeasureId%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotAmount%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].PreviousToDateQuantity%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].PreviousToDateAmount%></td>
etc. more columns
</tr>
</table>
div.scroll-content-grid21
{
overflow : auto;
width: 1072px; /* notice, smaller than the table width */
height: 500px;
}
table.regular
{
table-layout:fixed;
margin-top: 0.1em;
margin-bottom: 0.1em;
border-collapse: collapse;
text-align: left;
}
The first thing I can see is that you need to give width to your table header cells (th) as well. try this to see if it helps. Also have you given {overflow-x:auto} to td and th ?
Here's a sample for anyone else who needs it:
<html>
<head>
<style>
div.outer
{
width : 500px;
overflow : auto;
}
table
{
table-layout:fixed;
width: 100%; /* same as containing div */
}
th, td
{
border: solid 1px #ccc;
}
</style>
</head>
<body>
<div class="outer">
<div class="scrollable">
<table>
<thead>
<th style="width:50px">One</th>
<th style="width:300px">Two</th>
<th style="width:200px">Three</th>
<th style="width:200px">Four</th>
<th style="width:200px">Five</th>
</thead>
<tbody>
<tr>
<td>001</td>
<td>My really long description here</td>
<td>10.0 units</td>
<td>$100.00 dollars</td>
<td>$1000.00 total</td>
</tr>
<tr>
<td>002</td>
<td>This is number 2</td>
<td>5 units</td>
<td>$5.00 dollars</td>
<td>$25.00 total</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>