I have a table with one column having image and other columns having text. For one of the columns I wish to show additional information below main text but I wish for the main text to remain vertically centered.
This is the code I currently have:
.table {
width: 100%;
}
.thumbnail {
height: 150px;
}
.bigtext {
font-size: 2em;
}
.smalltext {
font-size: 0.65em;
}
table,
th,
td {
border: 1px solid black;
}
<table class="table">
<tr>
<td><img src="https://via.placeholder.com/180x320" class="thumbnail"/></td>
<td>
<div class="bigtext">Should be vertically centered</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
</td>
<td>Third cell</td>
<td>Forth cell</td>
</tr>
</table>
JSFiddle: https://jsfiddle.net/rxhz1v2f/18/
Goal:
I know it can be done with margins etc set in pixels but I would like it to be dynamic, meaning even working if there are, for example, two rows of text with class bigtext.
Edit:
I would like the solution to be HTML&CSS only. I can change the HTML structure within table cell, if necessary.
You can do it with JavaScript by finding the size of the sibling elements like this:
document.querySelectorAll(".bigtext:first-child").forEach(element=>{
// Find the size of all the non-big siblings
let siblingSize = 0
let nextSibling = element.nextElementSibling
while (nextSibling) {
if (!nextSibling.classList.contains("bigtext")) {
siblingSize += nextSibling.getBoundingClientRect().height
}
nextSibling = nextSibling.nextElementSibling
}
// Add a margin to the first .bigtext
element.style.marginTop = siblingSize + "px"
})
.table {
width: 100%;
}
.thumbnail {
height: 150px;
}
.bigtext {
font-size: 2em;
}
.smalltext {
font-size: 0.65em;
}
table,
th,
td {
border: 1px solid black;
}
<table class="table">
<tr>
<td><img src="https://via.placeholder.com/180x320" class="thumbnail"/></td>
<td>
<div class="bigtext">Should be vertically centered</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
</td>
<td>
<div class="bigtext">Should be vertically centered</div>
<div class="bigtext">Should be vertically centered</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
</td>
<td>Third cell</td>
<td>Forth cell</td>
</tr>
</table>
Getting height of the small texts by sText.clientHeight multiplying that with 3 number of small texts and adding that px value to padding top of BtextContainer
let sText = document.querySelector(".smalltext");
let BtextContainer = document.querySelector(".bTextContainer");
BtextContainer.style.paddingTop=sText.clientHeight*3+"px";
.table {
width: 100%;
}
.thumbnail {
height: 150px;
}
.bigtext {
font-size: 2em;
}
.smalltext {
font-size: 0.65em;
}
table,
th,
td {
border: 1px solid black;
}
<table class="table">
<tr>
<td><img src="https://via.placeholder.com/180x320" class="thumbnail" /></td>
<td class="bTextContainer">
<div class="bigtext">Should be vertically centered</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
<div class="smalltext">Should be below big text</div>
</td>
<td>Third cell</td>
<td>Forth cell</td>
</tr>
</table>
Related
I'm trying to create a table where in every cell, there is a small coloured square next to a text.
However, I want the square and the text to be on the same line, and I cannot do it.
Sadly I'm not a css or html master, I've tried many alignment options I found on this and other sites, but none of them worked.
You can look at a minimal example below to understand what I'm talking about.
Is there any way to do it in css? Thank you
.badge{
background-color: #000000;
width: 1em;
height: 1em;
border-radius: 25%;
}
<html>
<body>
<table border="1">
<tr>
<td>
<div class="badge"></div> not horizontally aligned text
</td>
</tr>
</table>
</body>
</html>
Instead of nesting a <div> for the badge, you could create a ::before pseudo element for each <td> and make it inline-block so the pseudo element stays inline with the text content. This way you can ensure each table data element will have the small colored square before the cells text content.
.badge::before {
content: "";
background-color: #000000;
width: 1em;
height: 1em;
border-radius: 25%;
display: inline-block;
vertical-align: middle;
}
/* Optionally, give the cells different colors */
.badge.two::before {
background-color: #ae7;
}
.badge.three::before {
background-color: #f06;
}
<html>
<body>
<table border="1">
<tr>
<td class="badge one">
some text in cell 1
</td>
<td class="badge two">
some text in cell 2
</td>
<td class="badge three">
some text in cell 3
</td>
</tr>
</table>
</body>
</html>
If you instead want to keep the same HTML structure, you could make the <td> a flexbox with display: flex to ensure the content is aligned in a row format (side-by-side). Using align-items will define how items are aligned along the cross axis.
.badge{
background-color: #000000;
width: 1em;
height: 1em;
border-radius: 25%;
}
td {
display: flex;
align-items: center;
}
<html>
<body>
<table border="1">
<tr>
<td>
<div class="badge"></div> not horizontally aligned text
</td>
</tr>
</table>
</body>
</html>
Use flexbox:
.badge {
background-color: #000000;
width: 1em;
height: 1em;
border-radius: 25%;
margin-right: 1em;
}
td {
display: flex;
align-items: center;
}
<html>
<body>
<table border="1">
<tr>
<td>
<div class="badge"></div>horizontally aligned text
</td>
</tr>
</table>
</body>
</html>
I have a page with two panels. Second panel contains some large table so even with wrapped content it can't be displayed on full width window. Than I've added a horizontal scroll to fix this problem but it seems like div doesn't want to fit large table size.
Fiddle link
After some research I've found how to force second panel to fit the table size with this css change:
.pane {
display: table;
}
updated fiddle link
But there is another issue. The width of first and second panels are different. How to force the first panel to take all avaliable width even if it hidden with horizontal scroll?
Is there any pure html/css solution for this?
As advised, use display:table;, it will allow container to shrink/expand according to content and beyond window's size.
But since you need also an overflow, you may add an extra wrapper in between to allow those children to grow beyond the window's width and match to the widest one, i gave it .buffer as a classname to give it some meaning:
example:
.list {
overflow-x: auto;
}
.buffer {
display: table;
}
.pane {
border: 1px solid red;
margin: 15px 0;
}
.pane .head {
width: 100%;
background: #959595;
}
.pane .body {
width: 100%;
}
.pane .body table {
border: 1px solid green;
}
<div class="list">
<div class="buffer">
<!-- this a buffer container to allow to beyond window's width if displayed as table element *-->
<div class="pane">
<div class="head">
Pane 1 header
</div>
<div class="body">
Some body
</div>
</div>
<div class="pane">
<div class="head">
Pane 2 header
</div>
<div class="body">
<table width="100%">
<tbody>
<tr>
<td>First</td>
<td>Second</td>
<td>Third</td>
<td>Fourth</td>
</tr>
<tr>
<td>content</td>
<td>content</td>
<td>content</td>
<td>some_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super big content</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
https://jsfiddle.net/8cepsL09/6/
Its NOT a pure html/css solution but it works
I've used jquery to get the width of the second and apply it to the first
$('#pane1').width($('#pane2').width())
.list {
overflow-x: auto;
}
.pane {
border: 1px solid red;
width: 100%;
margin: 15px 0;
display: table;
}
.pane .head {
width: 100%;
background: #959595;
}
.pane .body {
width: 100%;
}
.pane .body table {
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<div class="pane" id="pane1">
<div class="head">
Pane 1 header
</div>
<div class="body">
Some body
</div>
</div>
<div class="pane" id="pane2">
<div class="head">
Pane 2 header
</div>
<div class="body">
<table width="100%">
<tbody>
<tr>
<td>First</td>
<td>Second</td>
<td>Third</td>
<td>Fourth</td>
</tr>
<tr>
<td>content</td>
<td>content</td>
<td>content</td>
<td>some_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super_super big content</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
You'll need to add in jquery to your site and add id's to your panes (you can use other ways of accessing your panes, but I find that ids are easist)
you can add this to your css
table {
border-collapse:collapse; table-layout:fixed;
}
table td {
border:solid 1px #fab; width:25%; word-wrap:break-word;
}
and adapt the width to the amount of columns.
EDIT: fiddle.js here
It would also be possible to play around with something like e.g.
padding-right: 3000px;
margin-right: -3000px;
which would extend the space used by the element.
See https://www.sitepoint.com/css-extend-full-width-bars/ for more details...
Here is some mock code. Basically I have no control over the table elements ONLY the div's inside the td's. I need to be able to hover over any of the div's in the row and they all hover to the same state. Can this be done?
Fiddle
HTML and CSS:
.one {
background-color: #0000FF;
width: 200px;
height: 30px;
}
.two {
background-color: #ff0000;
width: 200px;
height: 30px;
}
.three {
background-color: #00FF00;
width: 200px;
height: 30px;
}
/*.one:hover, .two:hover, .three:hover {
background-color: #000;
}*/
.row1:hover {
background-color: #000;
}
<table>
<tr>
<td>
<div class="row1 one">
</div>
</td>
<td>
<div class="row1 two">
</div>
</td>
<td>
<div class="row1 three">
</div>
</td>
</tr>
</table>
In CSS there is no parent selector yet. Therefore, you can't do this directly.
However, you can try using :hover on the nearest common ancestor:
tr:hover .row1 {
background-color: #000;
}
.one {
background-color: #0000FF;
width: 200px;
height: 30px;
}
.two {
background-color: #ff0000;
width: 200px;
height: 30px;
}
.three {
background-color: #00FF00;
width: 200px;
height: 30px;
}
tr:hover .row1 {
background-color: #000;
}
<table>
<tr>
<td>
<div class="row1 one"></div>
</td>
<td>
<div class="row1 two"></div>
</td>
<td>
<div class="row1 three"></div>
</td>
</tr>
</table>
Note it's not exactly the same: if you hover the border between two cells, they will change color even if you aren't hovering any .row1.
I don't think that's possible using just CSS, given that you have no control / access whatsoever to the table or tr above. If you do have some access (or can say for sure that the divs will be wrapped in a tr, try this code:
(basically, put a rule on the grandfather tr)
tr:hover > td > div {
background-color: black;
}
https://jsfiddle.net/zbqzu21r/
Weird idea:
You have the parent tr which you cannot control. Try making a table and nesting it inside the td. I'm assuming you can easily control anything done on this table. So, put your selectors on this table, and be done with it.
.mytable:hover tr > td > .row1 {
background-color: black;
}
<tr>
<td>
<table class="mytable">
<tr>
<td>
<div class="row1 one">
</div>
</td>
</tr>
<tr>
<td>
<div class="row1 two">
</div>
</td>
</tr>
<tr>
<td>
<div class="row1 three">
</div>
</td>
</tr>
</table>
</td>
</tr>
I'm struggling to get my 3 tables to be centered in the page.
Here's a picture of what it looks like currently:
Basically (from look at the image), I want the second/middle table ("Work" table) to be the only table in center, and the other 2 tables ("About" and "Collaborate" tables; left and right from the middle, respectively) to have spread out a bit (using margin, I would assume).
Here's my HTML:
.fixedWidth2 {
margin: 0 auto;
width: 1000px;
height: 350px;
background-color: green;
border: 2px solid yellow;
}
.tableProp1 {
width: 200px;
float: left;
margin-left: ;
}
.tableProp1 tr td {
height: 200px;
color: red;
}
.tableProp2 {
margin-left: 40px;
width: 200px;
float: left;
}
.tableProp2 tr td {
height: 200px;
color: pink;
}
.tableProp3 {
margin-left: 40px;
width: 200px;
float: left;
}
.tableProp3 tr td {
height: 200px;
color: blue;
}
<div id="mainContent">
<div class="fixedWidth2">
<table class="tableProp1" border="1">
<tr>
<th>About</th>
</tr>
<tr>
<td>Learn more about me and my accomplishments.</td>
</table>
<table class="tableProp2" border="1">
<tr>
<th>Work</th>
</tr>
<tr>
<td>I tend to get involved with a lot of different projects. Ranging from a simple photoshop gig to having a small role in a television/pilot</td>
</tr>
</table>
<table class="tableProp3" border="1">
<tr>
<th>Collaborate</th>
</tr>
<tr>
<td>Have a brand new or idea of a project? Whatever help you may need, I may be of some assistance to</td>
</tr>
</table>
</div>
<!-- Fixed Width 2 DIV for Main Content DIV -->
</div>
<!-- mainContent DIV -->
Since you are using fixed widths for your tables and you're floating them, I would wrap them in a container, set the width on that to match all three tables+margin and set margin: auto on the container
.table-wrapper{
width: 680px;
margin: auto;
}
JSFIDDLE
Alternatively you can just use display: inline-block instead of float:left and add text-align: center to .fixedWidth2
ALT FIDDLE
I would not use <table> at all... table are good for tabular content, not for templating....
I would use DIV or even HTML5's <article> and <section>.
Think also about SEO, <h2> is a better mirror to your website semantic toward search engines than table's TH ...
To center three elements you can simply set them display: inline-block; with some vertical-align, than just setting the <div class="centered"> to text-align: center; will center-align your inner elements. You can also use float:left; but I've not covered that example.
http://jsbin.com/roruqo/1/
<div id="container">
<div id="slider"></div>
<div id="mainContent">
<div class="centered">
<div class="fixedWidth2">
<h2>About</h2>
<p>Learn more about me and my accomplishm...</p>
</div>
<div class="fixedWidth2">
<h2>Work</h2>
<p>I tend to get involved with a lot of d...</p>
</div>
<div class="fixedWidth2">
<h2>Collaborate</h2>
<p>Have a brand new or idea of a project?...</p>
</div>
</div>
</div><!-- mainContent DIV -->
</div>
h2, p{
padding:15px;
margin:0;
}
#container{
width:960px;
margin:0 auto;
background:#eee;
}
#slider{
background:blue;
height:400px;
}
.centered{
text-align:center;
}
.centered > div{
text-align:left;
}
.fixedWidth2{
min-height:170px;
background:#ddd;
display:inline-block;
vertical-align:top;
width: 250px;
margin: 15px;
}
.fixedWidth2 h2{
text-align:center;
background:#aaa;
}
<div id="mainContent">
<div class="fixedWidth2">
<div class="row">
<table class="tableProp1" border="1">
<tr>
<th>About</th>
</tr>
<tr>
<td>Learn more about me and my accomplishments.</td>
</table>
<table class="tableProp2" border="1">
<tr>
<th>Work</th>
</tr>
<tr>
<td>I tend to get involved with a lot of different projects. Ranging from a simple photoshop gig to having a small role in a television/pilot</td>
</tr>
</table>
<table class="tableProp3" border="1">
<tr>
<th>Collaborate</th>
</tr>
<tr>
<td>Have a brand new or idea of a project? Whatever help you may need, I may be of some assistance to</td>
</tr>
</table>
</div>
</div>
</div>
add this style in style sheet
.row {
margin: 0 auto;
width: 680px;
}
add "row " division and apply this style then check it's working properly.
How can I make a table in css/html like this:
I want to use only div, not <table> tags.
Code, yet:
<style>
.tab_in {
display: table-cell;
border: 1px dotted red;
padding: 4px 6px;
}
</style>
<div style="text-align:center;">
<div class="tab_in">
<div>a</div>
<div>b</div>
</div>
<div class="tab_in" style="vertical-align:middle;">c</div>
<div class="tab_in" style="vertical-align:middle;">d</div>
<div class="tab_in" style="vertical-align:middle;">e</div>
</div>
Use fluid grid system which uses percents instead of pixels for column widths. and handle the external width of it using a external container.
You can do something like:
JSFiddle Demo
HTML:
<div class="box">
<div class="row-fluid show-grid">
<div class="span4">
<div class="rowspan2">
<span class="valign-helper"></span>
a
</div>
<div class="rowspan2">
<span class="valign-helper"></span>
b
</div>
</div>
<div class="span4">
<div>c</div>
<div>d</div>
<div>e</div>
<div>f</div>
</div>
<div class="span4">
<div>g</div>
<div>h</div>
<div>i</div>
<div>j</div>
</div>
</div>
</div>
Note: to vertically align text you can also do using "display: table-cell" css property to the class 'rowspan2'. and remove the tag with class "valign-helper"
CSS:
body {
margin: 50px;
}
.box {
width:500px;
padding: 0 10px;
background-color: #000;
}
.show-grid [class*="span"] div {
background-color: #fff;
text-align: center;
min-height: 40px;
line-height: 40px;
margin-left: 0;
margin-top: 10px;
margin-bottom: 10px;
}
.show-grid [class*="span"] .rowspan2 {
height: 90px;
margin-bottom: 0;
}
.valign-helper {
display: inline-block;
height: 100%;
vertical-align: middle;
}
Here's an example of one way you might accomplish this:
http://jsfiddle.net/mori57/cDEGw/1/
html:
<table class="tab_out">
<tr>
<td rowspan="0" class="col">
<div class="tab_in">a</div>
<div class="tab_in">b</div>
</td>
<td><div class="tab_in">c</div></td>
<td><div class="tab_in">g</div></td>
</tr>
<tr>
<td><div class="tab_in">d</div></td>
<td><div class="tab_in">h</div></td>
</tr>
<tr>
<td><div class="tab_in">e</div></td>
<td><div class="tab_in">i</div></td>
</tr>
<tr>
<td><div class="tab_in">f</div></td>
<td><div class="tab_in">j</div></td>
</tr>
</table>
CSS:
.tab_out {
width: 800px;
margin-bottom: 20px;
text-align:center;
}
.tab_out td {
border:1px dotted red;
padding: 4px 6px;
margin-bottom: 0;
vertical-align:middle;
}
.tab_in {
display: block;
border: 1px dotted green;
}
Is this any closer to what you're looking for? I really don't see an efficient way to accomplish your layout without using a table, at this point. Mind you, the div inside each TD is optional, I just used it to show you where the element actually appears inside the table.