Fixed-width table with variable-width columns - css

I need a fixed-width table with columns which have a variable width, so depending on their content, but where the horizontal distance between these contents is the same.
This is what I get:
-----------------Table Width-----------------
|----Long Content----|---Content---|--More--|
This is what I want:
----------------Table Width------------------
|---Long Content---|---Content---|---More---|
Please note the count of the minus-sign in the content cells! When you measure the spaces between the content of the columns, by using a screenshot, you'll notice, that they aren't always exactly the same.
This is my markup:
<ul>
<li>Long Content</li>
<li>Content</li>
<li>More</li>
</ul>
This is my not working stylesheet:
ul {
display: table;
width: 600px;
}
li {
display: table-cell;
text-align: center;
border: solid 1px #000;
}
Here is my jsFiddle: http://jsfiddle.net/ATwqk/12/. How can I get the desired result?

If i understand this correctly you could try wrap a div fixed width around the ul. then width:100%; on the ul and width:50% on the li
http://jsfiddle.net/ATwqk/3/
#wrapper{
width:500px;
}
ul {
display: table;
width: 100%;
}
li {
display: table-cell;
text-align: center;
border: solid 1px #000;
width:50%
}
<div id="wrapper">
<ul>
<li>Long Contentdsdddddddddddd</li>
<li>Content</li>
</ul>
</div>

You need the left and right padding properties set to 2.5em. However, this will only work if either there are no breaks or every cell breaks its content.
ul {
display: table;
width: 300px;
}
li {
display: table-cell;
text-align: center;
border: solid 1px #000;
padding: 0 2.5em;
}

Try this on your ul tag. This should do exactly what you want.
ul
{
display: flex;
justify-content: space-between;
width: 600px;
}
Updated jsfiddle:
http://jsfiddle.net/ATwqk/19/

Related

Place span element next to image, but at the center vertically

I'd like to have an image slideshow with a next button that forms the entire right border of the image. Would it be possible to have the words "NEXT" display in the center of the red area, instead of on the same line as the image?
<ul>
<li></li>
<span>NEXT</span>
</ul>
li {
display: block;
width:200px;
height:100px;
display: inline-block;
border:1px solid;
}
span {
background-color:red;
padding-top:100px;
}
Fiddle here:
http://jsfiddle.net/PUQNg/217/
You have a few things wrong with your HTML and CSS that you should correct:
span is not a valid child of ul, make this a li instead
There's no point having display: block; and display: inline-block; on li, only the last display property will be used
To centralise the text in this case I would use a line-height set to the height of the li.
li {
border: 1px solid #000000;
display: inline-block;
height: 100px;
vertical-align: middle;
width: 200px;
}
.next {
background-color: red;
border: 0;
line-height: 100px;
width: auto;
}
<ul>
<li></li>
<li class="next">NEXT</li>
</ul>

How do I vertically align text inside an anchor element, which is nested within an unordered list

I have searched extensively and seen numerous examples on how to vertical-align text using the vertical-align property and the line-height property. However, all my efforts seem to bear no fruit as I am unable to get my text to align vertically. How do I do vertically align text to be centered? The height properties are not fixed so I can't use line-height.
HTML
<nav>
<ul>
<li>Login</li>
<li>Register</li>
<li>Programmes Offered</li>
</ul>
</nav>
CSS
nav
{
height: 30%;
width: 100%;
}
nav ul
{
height: 100%;
margin: 0px;
}
nav ul li
{
height: 33%;
width: 100%;
vertical-align: middle;
}
you may use a pseudo element displayed as an inline-box using full height of li and vertical-aligned to midlle. DEMO
body, html {
height:100%; /* needed for demo */
}
nav {
height: 50%; /* increased for demo */
width: 100%;
}
nav ul {
height: 100%;
margin: 0px;
}
nav ul li {
height: 33%;
box-shadow:inset 0 0 0 1px; /* show me li , for demo */
}
nav ul li:before {
content:'';
height:100%;
display:inline-block;
vertical-align: middle;
}
edit
If you also reset display and vertical-align on <a>, links can be spread on a few lines (demo below):
body,
html {
height: 100%;
}
nav {
height: 70%; /* height set for snippet demo purpose, could be really too much */
width: 100%;
}
nav ul {
height: 100%; /* will follow height, inherit height value , set in nav if any avalaible */
margin: 0px;
}
nav ul li {
height: 33%;
/* see me and my center*/
box-shadow: inset 0 0 0 1px;
background:linear-gradient(to top, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.2) 50%);
}
nav ul li:before {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
a {
display: inline-block;
vertical-align: middle;
}
<nav>
<ul>
<li>Login
</li>
<li>Register
</li>
<li>Programmes<br/> Offered
</li>
</ul>
</nav>
If you can use flexbox, you can get away with the following css:
CSS
ul li a {
display:flex; // Enables flexbox
justify-content: center; // Center on main axis
align-items: center; // Center on cross axis
}
Update ( using auto margins )
You can also do it like this:
ul li { display:flex }
li a { margin: auto }
/* These rules are just to make things easier to see. */
nav {
margin: 0 auto;
margin-top: 5rem;
border: 1px dotted green;
width: 100%;
}
ul {
padding: 0;
display: flex;
justify-content: space-around;
}
li {
height: 3rem;
padding: 2rem;
border: 1px dotted red;
}
/* Here are what I am trying to illustrate */
ul li {
display: flex;
}
a {
margin: auto;
/* or adjust them one by one, by targeting
the ones you want and setting
using each margin like this:
margin-top: auto;
margin-right: auto;
margin-bottom: auto;
margin-left: auto;
*/
}
<nav>
<ul>
<li>Login</li>
<li>Register</li>
<li>Programmes Offered</li>
</ul>
</nav>
vertical-align aligns inline elements with their siblings.. unless used in a table cell.
I don't think there's a by-the-book way of vertically aligning.. but this should work:
D E M O
nav ul li
{
background:#f1f1f1;
height: 33%;
width: 100%;
border-top:1px solid #e0e0e0;
}
nav ul li a
{
display:block;
position:relative;
top:50%;
-webkit-transform:translate(0,-50%);
-moz-transform:translate(0,-50%);
transform:translate(0,-50%);
}
Have you tried with
nav ul li a
{
height: 33%;
width: 100%;
vertical-align: 5px; //(you can make it 10px or -10px, just so it fits your style)
}
Your text is within the a tag, so adding a in the css may solve your problem :)

Adding margins to display: table-cell child element

I've been attempting to build a navigation using display: table. The code is a simple div as display: table, a ul for the display: table-row and each li as display: table-cell.
Each li has an a tag inside and I simply want to add a margin to a tag for the active page in the navigation defined by an .active class, however it seems to add the margin for every li.
Any idea what is going on here?
Working example: http://jsfiddle.net/Gxpb3/4/
Code
<div>
<ul>
<li>Pie</li>
<li>Pie</li>
<li>Pie</li>
<li class="active">Pie</li>
<li>Pie</li>
<li>Pie</li>
</ul>
</div>
div {
margin-top: 50px;
display: table;
width: 100%;
}
ul {
display: table-row;
max-width: 400px;
margin: 0 auto;
}
li {
display: table-cell;
text-align: center;
background: red;
height: 50px;
}
a {
color: #fff;
display: block;
background: black;
}
li.active a {
margin-top: 5px;
}
a:hover {
background: grey;
}
Well I've figured it out. Strangely, all the li elements increase in size when margin is added to one of the a tags. Adding vertical-align with any value seems to prevent them expanding and produces the desired effect.
However, I have no idea why this happens.
Fiddle: http://jsfiddle.net/2DGjV/

Fluid layout with even width navigation items

I'm building a site for mobile devices and therefore has a fluid layout.
My navigation list looks like this:
<ul>
<li>home</li>
<li>about</li>
<li>work</li>
<li>contact</li>
</ul>
Problem is, the first list item needs to be 100px only (left aligned always), and the other 3 split evenly, therefore is it possible to have even width for all list items except for the first one (without using javascript).
This is the simplest way I could think of:
ul { overflow: hidden; padding-left: 100px; position: relative; }
li { width: 33.33%; float: left; }
li:first-child { position: absolute; top: 0; left: 0; width: 100px; }
The main idea is taking the first li out of the flow (position: absolute) and adding a padding-left to the ul (space for the first li). Now if we set the percentage width for the other lis, they will take up the remaining space.
And here is a jsFiddle Demo. I added a red border on the ul which shows that because of the percentages lis will not accurately fill it.
I am unsure what mobile browsers you want to support, but except :first-child (which can be worked around by adding a class on the first list item) I assume they must support everything I used.
hmm a bit cludgy - but this seems to work, it does require nesting the list (second 3 links in separate list) and a span for the "home" link, theory is that you need the first link to float, width: 100px, then you need the second group not to float and have their overflow hidden so the group take up the remaining space.. then you float the 3 links # 33% inside the non-floated container
Example : HERE
CSS:
div {
width: 90%;
margin: 0 auto;
}
ul {
margin: 0; padding: 0; list-style: none; /* reset */
float: left;
width: 100%;
}
li {
float: left;
width: 100%;
text-align: center;
}
li span {
float: left;
width: 99px;
background: #eee;
border-right: 1px solid #000;
}
ul ul {
float: none;
overflow: hidden;
width: auto;
}
li li {
width: 33%;
background: #ffe;
border-right: 1px solid #000;
}
HTML:
<div>
<ul>
<li><span>home</span>
<ul>
<li>about</li>
<li>work</li>
<li>contact</li>
</ul>
</li>
</ul>
</div>
For what it's worth, this was what I was thinking of when I made my comment on your question:
http://jsfiddle.net/4t9fV/
ul {
display: table;
width: 100%;
background: #ccc;
table-layout: fixed
}
li {
display: table-cell;
text-align: center;
outline: 1px dashed red
}
li:first-child {
width: 100px
}

CSS List Question

I'm looking for a quick cross browser solution to my need for auto margins.
I have a simple list:
<ul>
<li>text</li>
<li>text</li>
<li class="possibly_last">text</li>
</ul>
With a width of 600px.
What I need is CSS code to make sure there is an even margin between each <li>.
So that they stretch across the full 600px evenly.
I may need to as a "last" class, but that's fine.
I just want a browser friendly way to do this.
Any help would be great, Thanks!
Try this:
<style>
li {
display: block;
float: left;
width: 32%;
}
</style>
If that does not work, try this:
<style>
li {
display: block;
float: left;
width: 200px; // or less
}
</style>
I take it you mean you don't want a margin after the last li? In that case, use the CSS :last-child selector:
ul li
{
margin-right: 10px;
width: 190px; // 190px = 200px - margin width
display: inline-block;
zoom: 1;
*display: inline;
}
ul li:last-child
{
margin-right: 0px;
}
Please note that this will NOT work in any internet explorer except IE9. Sorry :-(
As a fix, you could use JavaScript (notably jQuery) to edit the CSS of the last child.
An example here: http://jsfiddle.net/WtLAm/2/
Are you intending to float the list items so they stretch horizontally to fill the ul that way? if so, something like
<style type="text/css" media="screen">
ul {width: 600px;}
li {display: inline; float: left; width: 33%;}
</style>
would work.
I think this can't be done with margins, I suggest you this solution:
http://jsfiddle.net/wY5t6/
css:
ul li {
margin: 0;
display: block;
float: left;
width: 200px;
text-align: center;
}
ul {
width: 600px;
overflow:hidden;
}
If you need to set padding, background etc on list item than you can do it this way:
http://jsfiddle.net/wY5t6/1/
HTML:
<ul>
<li><span>text</span></li>
<li><span>text</span></li>
<li class="possibly_last"><span>text</span></li>
</ul>
CSS:
ul li {
margin: 0;
display: block;
float: left;
width: 200px;
text-align: center;
}
ul {
border: 1px green dotted;
width: 600px;
overflow:hidden;
}
li span {
background: yellow;
padding: 5px;
}

Resources