Table width in flex item - html

I have trouble with width size of a table inside a flex-item.
I want the flex item parent fit the table width (table-layout property must stay auto).
I do not have the same result on IE11 (KO) and chrome (OK).
Minimal reproduction : https://codepen.io/anon/pen/OjweJw?editors=1100.
.wrapper{
background-color:PALEGREEN;
display:flex;
padding: 15px 15px 0 15px;
font-size:20px;
}
.div1{
background-color:LIGHTCORAL;
flex-grow:0;
flex-shrink:0;
flex-basis:300px;
max-width:300px;
overflow:hidden;
}
.div2{
background-color:LIGHTBLUE;
flex-grow:1;
flex-shrink:1;
flex-basis:0px;
}
.div2 p{
border:10px solid black;
}
table, th, td {
border: 1px solid black;
}
<div class="wrapper">
<div class="div1">
<p>sidebarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
</div>
<div class="div2">
<p>tableau header</p>
<table>
<tr>
<th>Titre 1</th>
<th>Titre 2</th>
<th>Titre 3</th>
</tr>
<tr>
<td>Cellule A1jhkfdsahjfdslkjhfdsalkjhfdsalkjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsakjhfdsalkjhlkjhfdsalkjhfdsalkjhfdsakjfdsakjhfdsalkjhfdsalkjh</td>
<td>Cellule A2</td>
<td>Cellule A3</td>
</tr>
<tr>
<td>Cellule B1</td>
<td>Cellule B2kjfdsakjfdyslkjfdsalkfdsalkjfdsalkjfdsalkjfdsalkjfdsalkjfdsalkjfdsalkj</td>
<td>Cellule B3</td>
</tr>
</table>
</div>
</div>
How make it works on IE too ?
Thanks,
Autofocus.

Related

Split page into 3 columns with content in wider center column?

I need to create a 3-column layout where the center column is twice the width of the side columns, without using bootstrap, since bootstrap doesn't work in emails.
In bootstrap, it would be:
<div class="container">
<div class="col-3">
</div>
<div class="col-6">
<!-- All page content goes here -->
</div>
<div class="col-3">
</div>
</div>
How can I achieve this without using bootstrap?
Note
I found this code:
<div class="row">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
But that didn't seem to work.
For emails you need tables:
table {
width:100%;
table-layout:fixed;
border-spacing:0;
}
td {
width:25%;
}
td:nth-child(2) {
width:50%;
}
.column {
padding:15px;
border:1px solid;
}
<table class="row">
<tr>
<td class="column"></td>
<td class="column"></td>
<td class="column"></td>
</tr>
</table>
Especially for emails the simplest solutions are the best, so I'd recommended to use table with inline styles, like this:
table {
width: 600px;
}
td {
border: 1px solid #000;
}
<table cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td style="width: 25%; height: 20px;"></td>
<td style="width: 50%; height: 20px;"></td>
<td style="width: 25%; height: 20px;"></td>
</tr>
</tbody>
</table>
I am not sure in what sense the given example didn't work as this snippet gives columns of widths 25%, 50%, 25% as required in the question.
However, note that some email systems may not support CSS other than an inline style so in the snippet the styles have been put inline and padding etc removed as you will have to decide what to do about that and compensate in the width definitions. It may still be that email systems do not accept HTML even just with inline CSS but it depends on your exact use case whether this matters and how you will ensure the info is presented OK to the user if it is ignored.
<div>
<div style=" background-color:#aaa; width: 25%; float: left;">
<h2>Column 1</h2>
<p>Some text..</p>
</div>
<div style=" background-color:#bbb; width: 50%; float: left;">
<h2>Column 2</h2>
<p>Some text..</p>
</div>
<div style=" background-color:#ccc; width: 25%; float: left;">
<h2>Column 3</h2>
<p>Some text..</p>
</div>
</div>
As I wrote in the comment above, today, you can only use table display for emails. Flex and Grid will not work!
There is one more very important point. Template for emails does not have access to CSS, so all styles must be specified inside tags.
I made you a simple template for emails with content. Just use it. If you need to fix or modify something, then let me know.
<table style="width: 100%; border: 1px solid black">
<tr>
<th style="width: 25%; border:1px solid black">title 1</th>
<th style="width: 50%; border:1px solid black">title 2</th>
<th style="width: 25%; border:1px solid black">title 3</th>
</tr>
<tr>
<td style="border:1px solid black">content 1</td>
<td style="border:1px solid black">content 2</td>
<td style="border:1px solid black">content 3</td>
</tr>
</table>
Use inline-styles:
<div style="display: flex;">
<div style="flex: 25%; max-width: 25%">
column 1
</div>
<div style="flex: 50%; max-width: 50%">
column 2
</div>
<div style="flex: 25%; max-width: 25%">
column 3
</div>
</div>
.row{
display:flex;
height:150px;
border:2px solid red;
}
.column{
border:1px solid green;
margin:2px;
width:30%;
}
.column1, .column3{
flex-grow:1;
}
.column2{
flex-grow:2;
}
<div class="row">
<div class="column"></div>
<div class="column2 column"></div>
<div class="column"></div>
</div>
The flex grow should be a very quick solution for you. Run the code to see how it works.
The second bit of code you posted doesn't work because you haven't defined the row or column CSS classes.
You have a two main options:
Use the bootstrap classes by copying their code into a style tag in your email body.
Write your own classes to achieve this layout. Here's an example using display: flex.
.row {
height: 100vh;
width: 100vw;
display: flex;
}
#col1 {
height: 100vh;
flex-basis: 20%;
background-color: red;
}
#col2 {
height: 100vh;
flex-basis: 60%;
background-color: green;
}
#col3 {
height: 100vh;
flex-basis: 20%;
background-color: blue;
}
<div class="row">
<div id="col1"></div>
<div id="col2"></div>
<div id="col3"></div>
</div>
UPDATE:
For Emails, Tables will work for sure :) Yup you need to go for tables only. Because some email systems don't support external CSS.
litmus.com
.table{
width:100%;
}
tr td{
width:25%;
height:50px;
}
tr .second{
width:50%;
}
<table class="table" border="1" cellspacing="0" cellpadding="0">
<tr>
<td></td>
<td class="second"></td>
<td></td>
</tr>
</table>

How DIV & CSS work with Rowspan & Colspan?

I have studied few days about how to use div to create table cells and merge cells, Actually I can did this with TABLE, but can't do the same screen result in DIV, hope someone can help me drive me the better method or fix the code.
Actually, I want to make all the cells in same Width and Height (Except the Merged Area) in the full screen mode, but the problem was the merged cell at center. I tried many methods cannot make it working like the TABLE style.
Here is the result I want, but make with table:
<style>
html, body{
width:100%;
height:100%;
margin:0;
padding:0;
}
table {
border-width: 1px 1px 0px 0px;
border-spacing:0;
margin:0;
padding:0;
width: 100%;
height: 100%;
}
td {
border-width: 0px 0px 1px 1px;
}
table, td {
border-style: solid;
border-color: purple;
}
.w25 {
width:25%;
height:25%;
}
.w50 {
width:50%;
height:50%;
}
.w100 {
width:100%;
height:100%;
}
</style>
<table class='w100'>
<tr>
<td class='w25'>D</td>
<td class='w25'>E</td>
<td class='w25'>F</td>
<td class='w25'>G</td>
</tr>
<tr>
<td class='w25'>C</td>
<td class='w50' colspan=2 rowspan=2 >MERGED AREA</td>
<td class='w25'>H</td>
</tr>
<tr>
<td class='w25'>B</td>
<td class='w25'>I</td>
</tr>
<tr>
<td class='w25'>A</td>
<td class='w25'>L</td>
<td class='w25'>K</td>
<td class='w25'>J</td>
</tr>
</table>
And this is the code I currently making for DIV version, but no success to balanced all the the width and height in full screen.
<style>
html, body{
width:100%;
height:100%;
margin:0;
padding:0;
}
.table {
border-width: 1px 1px 0px 0px;
}
.intable {
border-width: 0px 1px 0px 0px;
}
.table, .intable {
display:table;
width:100%;
height:100%;
}
.cell {
display:table-cell;
}
.row {
display:table-row;
}
.cell {
border-width: 0px 0px 1px 1px;
width:25%;
}
.table, .intable, .cell {
border-style: solid;
border-color: purple;
}
</style>
<div class='table'>
<div class='row'>
<div class='cell' style="max-width:25%;">D</div>
<div class='intable'>
<div class='cell'>E</div>
<div class='cell'>F</div>
</div>
<div class='cell'>G</div>
</div>
<div class='row'>
<div class='intable'>
<div class='row'>
<div class='cell'>C</div>
</div>
<div class='row'>
<div class='cell'>B</div>
</div>
</div>
<div class='cell'>Merged Area</div>
<div class='intable'>
<div class='row'>
<div class='cell'>H</div>
</div>
<div class='row'>
<div class='cell'>I</div>
</div>
</div>
</div>
<div class='row'>
<div class='cell'>A</div>
<div class='intable'>
<div class='cell'>L</div>
<div class='cell'>K</div>
</div>
<div class='cell'>J</div>
</div>
</div>
Table Version JSFiddle
DIV Version JSFiddle
Wish somebody can fix the code!
Try adding another class to your merged column, like so:
<div class='cell merged'>Merged Area</div>
and change the css of the merged area, like so:
.merged{
width:50%;
height:50%;
}
The reason I did this is because you had the same class on your merged area, but you wanted the size to take up double the space of a normal cell. So all I did was add an additional class changing the width and height of the merged area to get the desired result.
Here is an updated Fiddle:
https://jsfiddle.net/6hx2uooz/4/

How to make a div to fit all available width even hidden with scroll?

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...

HTML & CSS: Can't center my tables

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.

HTML Table, first and last column fixed width and columns between dynamic, but equal width

Is it possible to have a table with width 100% (so the table fits the screen size), where the first and the last column have a fixed width, and the columns between take the rest, both 50%.
Like:
+--------------------+--------------------------------------+--------------------------------------+------------+
| width:300px; | with dynamic, equals next column | width dynamic, equals prevous column | width:50px;|
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------------------------------------+------------+
Try this:
As you can see the two centre column remain equal sized, due to the table-layout:fixed, even when the content is of different length. Try adding more and less content to the two centre columns.
JSFiddle: http://jsfiddle.net/RtXSh/
CSS
table {
width:100%;
border-collapse:collapse;
table-layout:fixed;
}
td {
border: 1px solid #333;
}
HTML
<table>
<tr>
<td style="width:300px;">
test
</td>
<td>
test test tes test test
</td>
<td>
test
</td>
<td style="width:50px;">
test
</td>
</tr>
</table>
Try using the pseudo element first-child and last-child
If I'm not mistaken the other columns will align equally by themselves. You might need to use the !important statement behind the first-child and last-child widths.
table{ table-layout: fixed; width: 100%; }
td { border: 1px solid black; }
td:first-child{ width: 100px; }
td:last-child{ width: 100px; }
<table>
<tr>
<td>100px</td>
<td>some text</td>
<td>some text</td>
<td>100px</td>
</tr>
</table>
However, as nurettin pointed out, if you use a thead and tbody section you have to style the header. Styling the td:first-child and td:last-child will not work.
table{ table-layout: fixed; width: 100%; }
td { border: 1px solid black; }
th:first-child{ width: 100px; }
th:last-child{ width: 100px; }
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>100px</td>
<td>some text</td>
<td>some text</td>
<td>100px</td>
</tr>
</tbody>
</table>
In my opinion, the simple, nice and easy way is that don't use the px and % together. If you are using table width 100%, then define width of first and last column in % as well. If you are interested in that, here is how you can do:
CSS:
.mytable {
width:100%;
border: 1px solid green;
}
.left{
width:30%;
border-right:1px dashed blue;
}
.mid1{
width:30%;
border-right:1px dashed blue;
}
.mid2{
width:30%;
border-right:1px dashed blue;
}
.right{
width: 10%;
border-left:1px dashed blue;
}
HTML:
<table class="mytable">
<tr>
<td class="left">Left Column, 30%</td>
<td class="mid1">Mid 1, 30% </td>
<td class="mid2">Mid 2, 30% </td>
<td class="right">Right, 10%</td>
</tr>
</table>
This can be handled by adding the style table-layout:fixed to the table element, and simply not specifying any width value for the columns you wish to evenly divide the width remaining after the fixed columns have been accounted for.
Further, using combinations of <colgroup> can provide robust variable-width scenarios.
I've created an example at JSFiddle: https://jsfiddle.net/3bgsfnuL/1/
<div style="position:relative; height:500px; width:100%;">
<table style="height:100%; width:100%; table-layout:fixed; text-align:center; border-collapse:collapse;">
<colgroup colspan="1" style="width:200px"></colgroup>
<colgroup colspan="3">
<col/>
<col style="width:30px"/>
<col/>
</colgroup>
<colgroup colspan="1" style="width:200px"></colgroup>
<tbody>
<tr>
<td style="background-color:silver;">left fixed</td>
<td style="border-right:1px solid black;">col 1</td>
<td style="background-color:red; color:white; border:1px solid black;">col 2</td>
<td style="border-left:1px solid black;">col 3</td>
<td style="background-color:silver;">right fixed</td>
</tr>
</tbody>
</table>
</div>
Nobody mentioned this one here <th> trick:
table{ table-layout: fixed; width: 100%; }
th:first-child{ width: 300px; }
<table>
<thead>
<tr>
<th>yourfirst300pxcolumn</th>
<th>fixedwidth</th>
<th>fixedwidth also</th>
</tr>
</thead>
<tbody>
<tr><td>300</td><td>something</td><td>something else</td></tr>
</tbody>
</table>
Note that in HTML5/CSS3, you can use grid layout to have more control over your tables. It's not that useful for this specific example, with pixel widths, where you can use table-layout:fixed as in Bazzz's answer, but it is useful if you want to use something like min-content.
The following works out of the box on Chrome and Firefox, but not in Safari:
table {
width: 100%;
display: grid;
grid-template-columns: 300px 1fr 1fr 50px;
/* Or, more usefully: */
/* grid-template-columns: min-content 1fr 1fr min-content; */
}
td {
display: block;
}
/* ignore <tr> when laying out the grid; just lay out the cells */
tr {
display: contents;
}
/* browsers can inject <tbody> into the DOM even if it's not in the HTML */
tbody {
display: contents;
}
(Note though that the table border-collapse property doesn't work in this layout, so you may have to fiddle with CSS pseudo-classes like :last-child in order to get your borders to behave the way you want.)
In Safari this doesn't work -- the rows don't break properly. (Although it does work if you use nested <div> elements instead of a <table> and apply similar styles.) However, a simpler layout with just one dynamic 1fr column does work in Safari:
table {
display: grid;
grid-template-columns: 300px 1fr 50px;
}
tbody {
display: contents;
}
tr {
display: contents;
}
td {
border: 1px solid #c0c0c0;
}
What about using jQuery for this and calling javascript function once your table is created or some other event (like click) happens?
See here (I created jsfiddle playground for this)
What it does is that it checks the width of fixed elements (width of the whole table, first and last cell). Then it calculates and assigns the width for the rest of the cells which should have the remaining width divided between them (based on how many there are and how much space is left). Of course this is just quick example of possible solution. It needs polishing (checking null objects, if remaining width is greater than 0, ...)