CSS flexible layout: flexible left column and variable fixed right column - html

I want to display the content of the div element in a single row. However the width of the ul element is unknown because it can have a number of child li elements. The h2 would always occupy the rest of the space. each li element has a width of 20px.
It would look something like this:
|----h2------------|li|li|li||
|----h2---------------|li|li||
HTML:
<div>
<h2>name</h2>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
I have found numerous solutions on the internet but not sure which to choose (proper solution vs hacks). browser compatibility is not an issue, it only needs to work on the latest version of chrome.
Update:
There will be multiple rows of div elements and the li elements should align.

The simplest, most compact and straight forward way is to use floats. If you know your elements will be different sizes, but you don't know exactly what they will be, there are 2 completely flexible ways to go about this.
This would be how to do it using display: table:
http://jsfiddle.net/8uTfp/1/
div {
display: table;
width: 100%;
}
h1, ul {
display: table-cell;
vertical-align: middle;
}
ul {
text-align: right;
}
li {
display: inline-block;
}
This would be how to do it using flexbox:
http://jsfiddle.net/8uTfp/
div {
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
ul {
margin-left: auto;
}
li {
display: inline-block;
}

You could float the h2 left, and the ul right.
div h2 { float: left; }
div ul { float: right; }

If the div's height and the list items' height are fixed and known values, you could try the followihg CSS (notice I added css classes):
.container{
height: 30px;
position: relative;
}
.container ul{
padding: 0; margin: 0;
/* Other reset rules here ... */
position: absolute;
top: 0;
right: 0;
}
.container ul li{
display: inline;
float: left;
height: 30px;
/* Other format rules here ... */
}
If you don't specify the div's height, it will be set by the h2 element's metrics, since absolutely positioned elements don't force the layout. I hope this helps.

Related

How to center text in li?

I am trying to have equal spacing between four different li elements, but I end up with this:
HTML:
<ul><li>Inbox</li></li><li>Drafts</li></li><li>Sent</li></li><li>Trash</li></ul>
CSS:
ul li {
width: 25%;
display: inline-block;
text-align: center;
}
I have tested the CSS and it is working as it should. I think the problem is that the li's don't all have the same amount of letters, so you end up with some weird visual effects. My reason for believing this:
(Equal spacing)
My approach with this issue is to center the li on the ul since the ul will naturally be the same width than the parent.
ul {
/* Use flex boxes to align li items */
display: flex;
justify-content: space-around;
/* Remove default padding from major browsers */
padding: 0;
/* Hide the default decorations for li items */
list-style: none;
}
ul > li {
/* Display the elements in one line */
display: inline-block;
}
Check out this JSFiddle to see it working.
Try this
ul {
width:100%;
margin-left: 0;
margin-bottom: 0
}
li {
list-style-type: none;
display: inline-block;
margin-right: 20px;
}

How can I make n number of <li> fit <ul> width?

I'm trying that all the li's width to match my ul's width, here's my code:
http://jsfiddle.net/4XR5V/2/
I already saw some questions on the site and some seem to work adding
ul {
width: 100%;
display: table;
table-layout: fixed; /* optional */
}
ul li {
display: table-cell;
width: auto;
text-align: center;
}
But it hasn't worked. My javascript function works, I dont know why in jsfiddle it doesn't work. How can I solve this issue?
Thanks!!
use flexbox. The children will fill up available area by default.
http://jsfiddle.net/4XR5V/3/
#tabs_header ul {
display: flexbox;
}
#tabs_header li {
flex: 1 1 auto;
}
Remove float: left. This declaration is not necessary when elements are displayed as table-cell. Floated elements shrinkwrap their contents.
Remove float: left; from list items:
#tabs_header li {
float: left;
}
fiddle1, fiddle2 - a working script ( by using jQuery )

CSS stretching child elements across parent element

I'm trying to get some list items to stretch across a list
This is the relevant code
#navbar ul
{
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
}
#navbar li
{
display: inline;
float: left;
width: 33.33%;
}
Here's what it normally looks like:
But sometimes when I leave the page and come back later (not after reloading) this happens:
Setting the individual item width to 33.3% makes it one pixel short and making it 33.333% makes the problem worse...
You could easily achieve this layout using css tables instead. Widely supported and semantically sound.
#navbar ul {
width: 100%;
display: table;
table-layout: fixed; /* makes all cells equal width */
}
#navbar li {
display: table-cell;
}
http://jsfiddle.net/kBnrz/1/
remove padding of parent of "ul"
Just fake it:
#navbar ul li{
width:33%;
}
#navbar ul li:last-child{
width:34%;
}
Also include this style:
* { box-sizing: border-box }
ref: http://www.paulirish.com/2012/box-sizing-border-box-ftw/
Suggestion:
#Miro try CSS Flexbox layout, it will help you, but it works only in modern browsers.
CSS Flexbox
The CSS Flexible Box Layout Model, or "flexbox", is one of the specification in CSS3. It provides for the arrangement of elements on a page such that the elements behave predictably when the page layout must accommodate different screen sizes and different display devices. For many applications, the flexible box model provides an improvement over the block model in that it does not use floats, nor do the flex container's margins collapse with the margins of its contents.
Here is one example
Html
<div class="box">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
</div>
StyleSheet
html, body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.box {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-content: center;
align-items: flex-start;
}
.box div.A {
order:1;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
.box div.B {
order:2;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
.box div.C {
order:2;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
Here is the Demo
This Link will help you.

Don't manage positioning (side-by-side)

I have following fiddle: http://jsfiddle.net/BFSH4/
As you see there are two issues:
The h1 and h2 aren't vertically aligned.
The nav and the content aren't horzontal alligned.
For the 1. I already tried margin and padding. No success...
The second one also isn't that easy the common ways of floating and using inline-block don't work...
What am I doing wrong?
I finally managed floating the header. The problem was that hgroup isn't a block element.
However even it worked after all I think it is better to use a real image for the enterprise name and slogan.
Now only the issue with the horizontal alignment fails.
I don't know why:
http://jsfiddle.net/BFSH4/2/
I can do what I want there is no way that they wan't to be side by side!
Solution for your first problem (found here):
HTML
<div class="header">
<span></span><img src="images/prototype.png" /><hgroup><h1>Prototype</h1><h2>SideBySide</h2></hgroup>
</div>
CSS
.header {
height: 160px;
border: 1px solid #8a2be2;
/* text-align: center; */
}
.header span {
height: 100%;
vertical-align: middle;
display: inline-block;
}
.header img {
display: inline-block;
height: 160px;
float: left; /* added, so the image will appear left to the text correctly */
}
.header hgroup {
margin: 0;
vertical-align: middle;
display: inline-block;
}
This solution depends on display: inline-block
Solution for the second problem:
.nav {
width: 229px;
display: block;
margin: 0 auto;
}
Live demo: http://jsfiddle.net/BFSH4/4/

CSS vertical alignment text inside li

I am displaying number of boxes in a row with fix height and width, generated from <li> tags.
now I need to align the text in the vertical center.
The CSS vertical-align has no impact, maybe I am missing something???
I am not looking for tricks using (margin, padding, line-height), these will not work because some text are long and will break into two lines.
Please find the actual code:
CSS code
ul.catBlock{
width:960px;
height: 270px;
border:1px solid #ccc;
}
ul.catBlock li{
list-style: none;
float:left;
display:block;
text-align: center;
width:160px;
height: 100px;
}
ul.catBlock li a{
display: block;
padding: 30px 10px 5px 10px;
height:60px;
}
HTML code
<ul class="catBlock">
<li>IP Phone</li>
<li>Dual SIM Switch Server</li>
<li>IP PBX</li>
</ul>
Define the parent with display: table and the element itself with vertical-align: middle and display: table-cell.
However many years late this response may be, anyone coming across this might just want to try
li {
display: flex;
flex-direction: row;
align-items: center;
}
Browser support for flexbox is far better than it was when #scottjoudry posted his response above, but you may still want to consider prefixing or other options if you're trying to support much older browsers. caniuse: flex
line-height is how you vertically align text. It is pretty standard and I don't consider it a "hack". Just add line-height: 100px to your ul.catBlock li and it will be fine.
In this case you may have to add it to ul.catBlock li a instead since all of the text inside the li is also inside of an a. I have seen some weird things happen when you do this, so try both and see which one works.
Surprisingly (or not), the vertical-align tool actually works best for this job. Best of all, no Javascript is required.
In the following example, I am positioning the outer class in the middle of the body, and the inner class in the middle of the outer class.
Preview: http://jsfiddle.net/tLkSV/513/
HTML:
<div id="container">
<span></span><div class="outer">
<span></span><div class="inner">
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
padding: 0; }
#container {
text-align: center;
height: 100%; }
span {
height: 100%;
vertical-align: middle;
display: inline-block; }
.outer {
width: 100px;
height: 200px;
padding: 0;
border: 1px solid #000;
vertical-align: middle;
display: inline-block; }
.inner {
background: red;
width: 30px;
height: 20px;
vertical-align: middle;
display: inline-block; }
Vertical align works by aligning the centers of elements that are next to each other. Applying vertical-align to a single element does absolutely nothing. If you add a second element that has no width but is the height of the container, your single element will move to vertically center with this no-width element, thus vertically centering it. The only requirements are that you set both elements to inline (or inline-block), and set their vertical-align attribute to vertical-align: middle.
Note: You may notice in my code below that my <span> tag and <div> tag are touching. Because they are both inline elements, a space will actually add a space between the no-width element and your div, so be sure to leave it out.
In the future, this problem will be solved by flexbox. Right now the browser support is dismal, but it is supported in one form or another in all current browsers.
Browser support: http://caniuse.com/flexbox
.vertically_aligned {
/* older webkit */
display: -webkit-box;
-webkit-box-align: center;
-webkit-justify-content: center;
/* older firefox */
display: -moz-box;
-moz-box-align: center;
-moz-box-pack: center;
/* IE10*/
display: -ms-flexbox;
-ms-flex-align: center;
-ms-flex-pack: center;
/* newer webkit */
display: -webkit-flex;
-webkit-align-items: center;
-webkit-box-pack: center;
/* Standard Form - IE 11+, FF 22+, Chrome 29+, Opera 17+ */
display: flex;
align-items: center;
justify-content: center;
}
Background on Flexbox: http://css-tricks.com/snippets/css/a-guide-to-flexbox/
There are no perfect answers provided here except Asaf's answer which doesn't provide any code nor any example, so I would like to contribute mine...
Inorder to make vertical-align: middle; work, you need to use display: table; for your ul element and display: table-cell; for li elements and than you can use vertical-align: middle; for li elements.
You don't need to provide any explicit margins, paddings to make your text vertically middle.
Demo
ul.catBlock{
display: table;
width:960px;
height: 270px;
border:1px solid #ccc;
}
ul.catBlock li {
list-style: none;
display: table-cell;
text-align: center;
width:160px;
vertical-align: middle;
}
ul.catBlock li a {
display: block;
}
As explained in here: https://css-tricks.com/centering-in-the-unknown/.
As tested in the real practice, the most reliable yet elegant solution is to insert an assistent inline element into the <li /> element as the 1st child, which height should be set to 100% (of its parent’s height, the <li />), and its vertical-align set to middle. To achieve this, you can put a <span />, but the most convenient way is to use li:after pseudo class.
Screenshot:
ul.menu-horizontal {
list-style-type: none;
margin: 0;
padding: 0;
display: inline-block;
vertical-align: middle;
}
ul.menu-horizontal:after {
content: '';
clear: both;
float: none;
display: block;
}
ul.menu-horizontal li {
padding: 5px 10px;
box-sizing: border-box;
height: 100%;
cursor: pointer;
display: inline-block;
vertical-align: middle;
float: left;
}
/* The magic happens here! */
ul.menu-horizontal li:before {
content: '';
display: inline;
height: 100%;
vertical-align: middle;
}
Simple solution for vertical align middle... for me it works like a charm
ul{display:table; text-align:center; margin:0 auto;}
li{display:inline-block; text-align:center;}
li.items_inside_li{display:inline-block; vertical-align:middle;}
Give this solution a try
Works best in most of the cases
you may have to use div instead of li for that
.DivParent {
height: 100px;
border: 1px solid lime;
white-space: nowrap;
}
.verticallyAlignedDiv {
display: inline-block;
vertical-align: middle;
white-space: normal;
}
.DivHelper {
display: inline-block;
vertical-align: middle;
height:100%;
}
<div class="DivParent">
<div class="verticallyAlignedDiv">
<p>Isnt it good!</p>
</div><div class="DivHelper"></div>
</div>