css - stretched and evenly spaced horizontal menu - html

I hope, you can help me, I have a horizontal menu, my problem is the following:
The first is normal stretch with table, the second is what I want: stretch + even gaps between texts.
I achieved this with additional non breaking spaces, but it works only by fixed menu widths, so if I change the menu width I have to change the count of the nbsp characters. Is there any way to do this with css, and without those non breaking spaces?
The count of the menupoints and the menu width can change, so I need an automatical solution without javascript. No settings by individual columns, unless you can give me an algorithm which I can run on server side.
I don't think this is possible with css only, but I'm not a css guru, that's why I asked....
<style>
* {
margin: 0px;
padding: 0px;
font-size: 16px;
}
table {
width: 400px;
}
td {
border: 1px solid blue;
text-align: center;
}
</style>
<table>
<tr>
<td>aa</td>
<td>aaaaaaaaaaaaa</td>
<td>aaaaaaaaa</td>
</tr>
</table>
<table>
<tr>
<td> aa </td>
<td> aaaaaaaaaaaaa </td>
<td> aaaaaaaaa </td>
</tr>
</table>

Not sure of all the parameters here ("stretch" is not very clear), but wouldn't some left and right padding on the links do it? Because this is a menu, I won't use a table but a <ul> instead. There are plenty of variations on this if it's not what you want:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
ul, li {margin: 0; padding: 0;}
ul {list-style: none; display: table; border-spacing: 5px; }
li {display: table-cell; background: #f7f7f7; border: 1px solid blue; }
li a {padding: 0 30px;}
</style>
</head>
<body>
<ul>
<li>aa</li>
<li>aaaaaaaaaaaaa</li>
<li>aaaaaaaaa</li>
</ul>
</body>
</html>

Edit: The below answer does not work well with Internet Explorer versions as recent as IE 11. Its algorithm for cell sizing appears to work differently than other browsers.
While this will require some cross-browser testing, here's what I've been using:
http://jsfiddle.net/aaronadams/j3cEQ/
HTML:
<p>Default spacing:</p>
<ul>
<li>aa</li>
<li>aaaa aaaa aaaa</li>
<li>aaa aaa aaa</li>
<li>aa aa</li>
</ul>
<p>Even spacing:</p>
<ul class="even">
<li>aa</li>
<li>aaaa aaaa aaaa</li>
<li>aaa aaa aaa</li>
<li>aa aa</li>
</ul>
CSS:
ul {
display: table;
margin: 0 auto;
padding: 0;
width: 100%;
max-width: 30em;
text-align: center;
}
li {
display: table-cell;
margin: 0;
padding: 0 0.125em;
white-space: nowrap;
}
.even li {
width: 1%;
}
So far, this is providing me with a menu that works really well across all screen sizes; on mobile it shrinks to screen width, on desktop it grows up to a certain size, and the links are always evenly spaced.
Credit here for the inspiration: https://stackoverflow.com/a/16509901/802414

You can set the width for the individual columns.
JSFiddle
HTML
<table>
<tr>
<td class="first">aa</td>
<td class="second">aaaaaaaaaaaaa</td>
<td class="third">aaaa aaaaaaaaaaaaa</td>
</tr>
</table>
CSS
table {
width: 400px;
}
td {
border: 1px solid #d3d3d3;
text-align: center;
}
.first {
width: 30%;
}
.second {
width: 45%;
}
.third {
width: 30%;
}

JSFIDDLE
You can set the "padding left and right for individual column
HTML
<table>
<tr>
<td class="first">aa</td>
<td class="second">aaaaaaaaaaaaa</td>
<td class="third">aaaa aaaaaaaaaaaaa</td>
</tr>
</table>
CSS
table { width: 400px; }
td { border: 1px solid #d3d3d3; text-align: center;}
.first { padding: 0 3em; }
.second { padding: 0 2em; }
.third { padding: 0 4em; }

This can be achieved with CSS by making the parent element text-align: justify, and the child elements display:inline-block; However, justified text only works properly when there's at least 2 lines. The pseudo :after element is used to force an extra (very tiny) line:
#container {
height: 125px;
text-align: justify;
border: 10px solid black;
font-size: 0.1px; /* IE 9/10 don't like font-size: 0; */
min-width: 600px;
}
#container div {
width: 150px;
height: 125px;
display: inline-block;
background: red;
}
#container:after {
content: '';
width: 100%; /* Ensures there are at least 2 lines of text, so justification works */
display: inline-block;
}
Credit to https://css-tricks.com/equidistant-objects-with-css/ for this technique.

Related

Table cell break word won't shrink

I often use this HTML/CSS structure to create a mobile-friendly table (It changes layout on narrow (mobile) screens; something very lacking in CSS frameworks) and it has been quite reliable for me. In my main project I have several tables with lots of data and varying widths.
If you open this codepen and change the view to 'debug' you can shrink the page width. Past 500px the table layout will change. The thead is hidden, secondary labels are shown and the tds are set to display: flex. (I like to use the responsive device toolbar in the inspector).
Under the table is a more simple set of divs, that behaves the way I want the divs inside the TD to work, but for some reason, the second div inside the td stops shrinking at a certain point. I have tried different combinations of word-wrap and white space but so far no luck. Seems the difference has to do with these divs being inside a table...
Is this just a limitation of tables or is there a way I can make the right div shrink like the second example?
Thanks!
https://codepen.io/sinrise/pen/qoypYJ
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>number</th>
<th>content</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="td-label">number</div>
<div>this is the first one</div>
</td>
<td>
<div class="td-label">number</div>
<div>this is the second one</div>
</td>
</tr>
</tbody>
</table>
<div class="cont">
<div class="in1">oneoneone oneone one oneoneoneoneoneon</div>
<div class="in2">two two twotwotwo twotwotwotwo</div>
</div>
table { width: 100%; table-layout: fixed; margin: 0 0 10px; }
th { padding: 10px 10px 0; text-align: left; }
td { padding: 10px; border: 1px solid #ccc; }
.td-label {
display: none;
min-width: 100px;
max-width: 100px;
font-weight: bold;
}
#media(max-width: 500px) {
thead { display: none; }
td {
display: flex;
margin: 0 0 10px;
> div:not(.td-label) {
word-wrap: break-word;
min-width: 1px;
}
}
.td-label {
display: table;
}
}
.cont {
display: flex;
border: 1px solid black;
> div {
&:first-of-type {
min-width: 100px;
max-width: 50px;
}
min-width: 1px;
border: 1px solid #aaa;
word-wrap: break-word;
}
}
The trick is to set the table width to 100%, add a min-width to the second div, and set display: table on the second div. I updated the pen and code above to reflect.

CSS to display table row headers above data cells

Suppose I have a table like this on an HTML page, with a purple border around the th cells and a green border around the td cells:
Some code that produces this (the CSS for the view-small class isn't in use in the above display but it's about to be explained):
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Table Transformation</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'>
<style>
body { font-family: "Opens Sans", sans-serif; }
td { border: 1px solid green; }
th { border: 1px solid purple; }
.view-small table { display: block; width: 100%; }
.view-small tbody { display: block; }
.view-small tr { display: block; width: 100%; margin: 2em auto; position; relative; }
.view-small th { display: block; width: 100%; position: absolute; left: 50%; transform: translateX(-50%); }
.view-small td { display: inline-block; height: 1em; width: 30%; transform: translateY(1.5em); }
</style>
</head>
<body class="">
<h1>Table Example</h1>
<table>
<tr>
<th>Numbers</th>
<td>One</td>
<td>Two</td>
<td>Three</td>
</tr>
<tr>
<th>Countries</th>
<td>Canada</td>
<td>Mexico</td>
<td>Guatemala</td>
</tr>
<tr>
<th>Planets</th>
<td>Mars</td>
<td>Jupiter</td>
<td>Saturn</td>
</tr>
</table>
<p>End of test</p>
</body>
</html>
We were thinking that for smaller devices, it would be neat if we could save horizontal space by display each row header over its corresponding data cells. If I set class="view-small" in the body tag in the code above, I get this in Chrome on Windows and pretty much the same thing in Firefox and IE11:
This demonstrates what I'm going for. What I'd really like to achieve includes having the data cells take up the horizontal space that the full row would have occupied. In the above code, I have their width set artificially to 30%, but that isn't ideal!
I'm going to tinker with this some more, but I thought I'd see whether anyone else has tried anything like this or seen a solution somewhere!
Try to change the width and margin values. The total value of width (including both horizontal margins) should be around 33%. These '3' after dot make it more precise.
div{
width: 30.3333333333%;
margin: 0 1.5%;
display: inline-block;
border: 1px solid black;
height: 20px;
box-sizing: border-box;
float: left;
}
<div></div>
<div></div>
<div></div>

Make button occupy full height inside a TD element in IE9

I've been trying to make a button which is inside a td cell in IE9. It's working fine on chrome and firefox (although the latter involved bubbling up height:100% to the td, tr and table elements). Do you have any idea how can I solve this problem using only CSS?
Here's the HTML:
<table>
<tr>
<td>
<span class="stuff">stuff</span>
</td>
<td class="the-td">
<button class="problem-here">
<span>stuff</span>
<span>more stuff</span>
</button>
</td>
</tr>
<tr>
<td>stuff</td>
<td>stuff!</td>
</tr>
</table>
And the CSS:
table {
border-collapse: collapse;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
td, tr {
padding: 0;
margin: 0;
height: 100%;
}
tr {
border: 1px solid black;
}
.problem-here {
margin: 0;
padding: 0;
background: none;
border: none;
background: lightgreen;
width: 100%;
height: 100%;
}
.stuff {
line-height: 100px;
}
.the-td {
width: 70%
}
button span {
display: block;
}
And, finally, here's a fiddle with the problem: https://jsfiddle.net/vh3jodap/10/
Thanks in advance
EDIT: here's a pic of what's happening right now:
http://i.imgur.com/J3hbWTj.png?1
In IE, in order for an element to have height:100%;, all parent elements must have height:100%;.
Any parent missing the height:100%; will cause IE to ignore it all.
Warning There's a high probability your table will grow bigger entirely
Hope this helps!

Fixed height of table row in html

I have a table hosted in a div. Neither the table nor the hosting div has a height specified.
After the table header row, each subsequent row looks like this:
<tr class="movie-info-row">
<td>
<div class="movie-cover">
<img class="movie-image" src="" />
<a class="movie-link" href="" target="_blank">IMDb</a>
</div>
</td>
<td colspan=5>
<div class="movie-details">
<p class="movie-file"></p>
<div class="movie-div-left">
<p class="movie-category"></p>
<p class="movie-director"></p>
<p class="movie-insertdate"></p>
</div>
<div class="movie-description-container">
<p class="movie-description"></p>
</div>
</div>
</td>
</tr>
I want each table row (except for the header) to have the same fixed height but I just can't get it to work after hours of trying all kinds of approaches (and of course searching on stackoverflow and elsewhere).
My css (in less syntax) looks like this:
.movie-info-row {
height: 240px;
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
height: 100%;
overflow: hidden;
}
}
.movie-cover {
border: 1px solid black;
width: 130px;
height: 100%;
overflow: hidden;
}
.movie-details {
border: 1px solid black;
height: 100%;
overflow: hidden;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
float: left;
width: 40%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
float: right;
width: 60%;
overflow: hidden;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
As you can see I have fixed the height of the row to 240px and for good measure have each td height set to 100% with overflow hidden.
The trouble maker is the description text, which can be quite long and it messes with the table row height. As you can see I have set overflow to hidden in many places (which is probably overkill).
Note: This is not browser specific. I am not even using IE. I am testing it with firefox and chrome (both latest versions).
I am really at a loss. What am I doing wrong? Any help would be greatly appreciated.
ETA:
Here's a picture of a table row as it looks now: SampleRow
As you can see the description text takes the row height with it. I want it limited to a fixed height - basically the hight of the title image. And yes, I want all the information (with more to come) in there. So that is non-negotiable.
Too many hiddens and floats and whatnot. Simplify and conquer. Also you have nested selectors inside of another selector (p{} and td{})
Demo Fiddle
CSS:
.movie-info-row {
height: 240px;
}
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
border: 1px solid black;
height: 100%;
}
div, p {
display: table-cell;
}
.movie-cover {
width: 130px;
overflow: hidden;
}
.movie-details {
height: 100%;
width: 100%;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
width: 35%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
width: 55%;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
By the looks of your HTML all of your data will go into one table cell is this how you want it?
Why not structure it like using individual tags for the headers with a colspan of what ever and then do a new for each row you need along with its data like this?
<tr>
<th colspan=2>Header</th>
</tr>
<tr>
<td>cell 1 data</td>
<td>cell 2 data</td>
<tr>
Then you can do this in the css, which would give you this same fixed height for all the rows:
tr {
height: 240px;
}
That way you can just use the table headers to describe each column and use a lot less code to make it work properly. Or from what I understand you are trying to do.

Horizontally align div with display: table-cell

I have a table with bars in it. I use display: table-cell in order to align the contents at the bottom. The problem is that the container divs no longer align horizontally over their corresponding THs (their width is not set)
Here is a jsFiddle that shows the problem
The Problem
The problem when using the table-cell-attribute is that it behaves like "a real table cell" and no more like a block- or inline-element. When the parent elements table-rowand table are missing they are generated anonymously. So the box will loose all the things like margin.
You can read more about this here: "Tables in the visual formatting model"
I rebuild your HTML structure a little and this seems to work fine:
DEMO
http://jsfiddle.net/insertusernamehere/XPSQG/
CSS
<style>
#graph th {
background: red;
}
#graph td {
min-width: 30px;
margin: 0;
padding: 0;
color: #222222;
}
#graph div {
display: block;
position: relative;
margin: 0 auto;
width: 30px;
max-width: 30px;
height: 100px;
background-color: #EFEFEF;
border: 1px solid #000000;
}
#graph span {
position: absolute;
left: 0;
top: -20px;
width: 100%;
color: #222222;
font-size: 16px;
line-height: 16px;
text-align: center;
}
#graph p.color {
position: absolute;
right: 0;
bottom: 0px;
width: 100%;
margin: 0;
color: #222222;
}
#graph p.color.c1 {
background: #0f0;
}
#graph p.color.c2 {
background: blue;
}​
</style>
HTMl
<div id="graph">
<table>
<tr>
<td><div><p class="color c1" style="height:20px;"><span>1</span></p></div></td>
<td><div><p class="color c2" style="height:30%;"><span>2</span></p></div></td>
<td><div><p class="color c1" style="height:40%;"><span>3</span></p></div></td>
<td><div><p class="color c2" style="height:50%;"><span>4</span></p></div></td>
</tr>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>Some long value</th>
</tr>
</table>
</div>
How it works
It basically places the content (green percentage <p>-tags) of the columns on the bottom. To have the numbers on top of that you can easily place them within the <p>-tag and them "move them out" again. This is done by this part:
top: -20px;
font-size: 16px;
line-height: 16px;
This says that the line-height and the font size are 16px. It would be enough to set top: -16px to move it out completely - the additional 4px add a nice padding. :)
Hope you get the idea.
Note
Somewhere you used this attribute:
countunit="0_1_0"
As this is not valid HTML please use the data-prefix:
data-countunit="0_1_0"
This is valid HTML5 and it also won't cause any trouble in older browsers.
There is a trick to center horizontally an element with display: table-cell inside another element.
Say the surrounding element has the class .table-wrapper and the inner element has .table-cell. Use the following CSS:
.table-wrapper {
display: table;
width: 100%;
text-align: center;
}
.table-cell {
vertical-align: middle;
}
This way you center the text or whatever you want inside .table-cell vertically and also horizontally.