Evenly spaced list items without JavaScript - html

I have a design that I have to implement where the designer has a top navigation with evenly spaced items.
I have used an unordered list for this. The only way I could get the items evenly spaced is to use javascript (it is a CMS or the number of LIs can vary).
The problem I have is the LIs start out with no padding then the padding gets added by JS, when you flick between pages you see a noticeable jump.
Is there any way to achieve the same result through HTML, if possible avoiding tables?

Make your list items display:inline-block and then give them a width. The width should be in em units so it resizes with the text.
Won't look nice on IE6, but should be readable/navigable.

If we're talking evenly spaced horizontally, you want display: table-cell
ul { display: table; width: 100% }
li { display: table-cell }
Note that you do need the parent container to be display: table if you want it to take up all of the available width.

Related

How can I do this with CSS and HTML?

It's hard to explain, but I'll try. I am trying to create a grid of divs that will never go off the page horizontally. Hence, the bottom scroll bar will never show. Instead, divs that are pushed off the window will wrap to the next row. There may not be as many divs on the bottom row as there are on the previous. In this case, the divs on the bottom row must be centered in the window. As the window resizes, the margins between the divs should expand or shrink to equalize the space between them. If the window resizes enough, the number of columns should change to fit the divs. Hopefully this image will help:
float:left and display:inline-block are close, but they don't resize margins and are not centered. I would like this to be done with pure CSS and HTML, but I do know JavaScript if it is necessary.
You can achieve this by using flexbox
Demo
The key parts are:
.grid {
display: flex;
flex-wrap: wrap;
justify-content: space-around
}
.grid > div {
flex-basis: 300px;
}

Wrap elements around an image with flexbox (no float), or anything else

I am working on a page where I would like a responsive img to align to the left of my section flex container, and the h1 & p text the right of the image, using flexbox.
I have more text and elements in the section flex container, but I would like them to be below the img.
Goal:
I am using codepen as a sandbox to get things done. But for some reason, the h1 is not horizontal but aligning vertically. The image is not keeping it's aspect ratio as the screen size decreases. And the rest of the elements won't stack below each other.
For small screens I would like the elements to just stack below each other in this order:
img
h1
p
a
a
etc...
I am working on a page where I would like a responsive img to align to the left of my section flex container, and the h1 & p text the right of the image, using flexbox.
But for some reason, the h1 is not horizontal but aligning vertically... And the rest of the elements won't stack below each other.
What you're missing are nested flex containers.
You can convert an element into a flex container with display: flex or display: inline-flex. Then all the children of this container become flex items and accept flex properties.
But you can also make flex items into flex containers.
This enables you to mix rows and columns deep into the HTML structure.
I've made some basic revisions to your codepen, as an example: http://codepen.io/anon/pen/xVamQQ?editors=1100
I altered the structure in order to accommodate alternating pattern of row and column flow. It looks like you already have a grasp of the fundamentals of flexbox. What I am concerned with is the lack of any padding and the height given to main was 1000vh. That's literally 10 viewports stacked on top of each other.
main { background-color: Gainsboro; height: 1000vh; overflow-y: scroll; }
CODEPEN

Center align horizontal <ul> with left-aligned rows

I am able to center horizontal list with text-align:center, but I wonder how can I keep it centered inside container, but has rows aligned left.
My container has percent width, so I need it working when resizing window and blocks are reordering
Please check the sample image below to understand my problem:
UPDATE:
Please find JsFiddle as per request
I need to center my <ul> inside div.container
Use this:
ul {
margin: auto;
}
li {
float: left;
}
See this fiddle:
You already know to center the <ul> with margin: auto;
The key is to adjust the <li> within it.
You can do that by using float: left;
Alternatively: you can set display: inline-block;
Both have a similar effect, but aren't identical. Play w/it.
By providing margins & percentage widths, you can play w/size and separation of the elements.
Since these are all block-level elements, they'll stack up & wrap automatically.
By floating or changing display of the <li> you keep them left-aligned within their parent element (the <ul>).
Also, by using separate CSS classes instead of targeting the <li> element directly, you leave things flexible in case you want to have a right-aligned list, or some other options later.
Wrap your boxes within another div.
You can then center that div with display: block; margin: 0 auto;, while keeping the boxes left-aligned.

div aligning content to other div

On my website i have the following layout:
outer-div with display: table
inner-div with display: table-row and width/height 100%
list-div with display: table-cell and width 25%
detail-div with display: table-cell and height 75%
Inside the list-div there is a ul with a few li elements. In the detail-div there is another div with width/height 100%. Here is an image how it looks at the beginning:
http://puu.sh/5e1wo.png
Notice the top margin of the list elements. When i click on one of the projects the idea is to add its (html-)description inside the detail-div element. While it works it oddly also affects the margin of the list-elements as you can see in the next pictures: http://puu.sh/5e1HI.png
http://puu.sh/5e1Iq.png
It somehow seems like the list elements are aligned to the content in the other div even if their first common anchestor is like 3 levels above. Is there a way to avoid this?
Open next inline-element using webkit-triads and then cross-ckeck the view with what u want. it works with chrome. do u have chrome or not?

Make div fill remaining space of parent

I need some help with positioning divs. The HTML structure is as follows:
<div class="container">
<div class="item">
<div class="left">
lorem lorem
</div>
<div class="right">
<p>right</p>
<p class="bottom">bottom</p>
</div>
</div>
</div>
And I have the following CSS:
.container {
float: left;
padding: 15px;
width: 600px;
}
.item {
float: left;
padding: 15px;
width: 570px;
}
.left {
float: left;
padding: 40px 20px;
margin-right: 10px;
}
.right {
position: relative;
float: left;
}
.bottom {
position: absolute;
bottom: 0;
}
The width and height of the left div is dynamic.
What I want to achieve is:
Make the height of the right div equal to height of the left div.
Make the width of the right div fill the rest of the div with class item.
The paragraph with class bottom should be at the bottom of the right div.
Here is a simple image that represents my goal:
And a link to a JSFiddle demo.
Getting the correct position and width of .bottom appears to be the biggest hurdle for a cross-browser, CSS solution.
Options
1. Floats
As #joeellis demonstrated, the flexible widths can be achieved by floating only the left column, and applying overflow:hidden to the right column.
The position of .bottom cannot be achieved in any browser. There's no CSS solution for floated columns with equal, variable height. An absolutely positioned .bottom element must be inside the right column div, so that 100% width would give it the correct size. But since the right column won't necessarily be as tall as the left column, positioning .bottom with bottom:0 won't necessarily place it at the bottom of the container.
2. HTML tables and CSS tables
The flexible widths can be achieved by giving the left cell a width of 1px and not specifying a width for the right cell. Both cells will grow to fit the content. Any extra space will be added to the right cell alone.
If .bottom is inside the right table cell, the position can't be achieved in Firefox. Relative position has no effect in a table cell in Firefox; absolute position and 100% width would not be relative to the right table cell.
If .bottom is treated as a separate table cell in the right column, the correct heights of the right and bottom table cells cannot be achieved in any browser other than Firefox. Table cells aren't flexible in height the same way they are in width (except in Firefox).
3. CSS3 flexbox and CSS3 grids
Flexbox and grids are the promising layout tools of the near future. But flexbox isn't supported by IE9 or earlier, and grids aren't supported by any browser other than IE10. Haven't tested if either can achieve this layout, but browser support may prevent them from being an option at present.
Summary
Floats don't offer a solution for any browser.
HTML tables and CSS tables don't offer a cross-browser solution.
Flexbox doesn't offer a potential solution for IE9 or earlier (and may or may not offer a solution to other browsers).
Grids only offer a potential solution to IE10 (and may or may not offer a solution there).
Conclusion
There doesn't appear to be an adequate CSS solution at present, one that would work in enough relevant browsers, with the possible exception of flexbox (if support for IE9 and earlier isn't required).
jQuery
Here's a couple modified demos that use jQuery to force the columns to have the same height. The CSS and jQuery for both demos is the same. The HTML only differs by how much content is in the left and right column. Both demos tested fine in all browsers. The same basic approach could be used for plain JavaScript.
Taller content on the left
Taller content on the right
To keep things simple, I moved the internal padding for the left and right div to a child element (.content).
Sibling elements of same height and staying on the same row can be achieved by displaying them as table-cell and parent as display: table.
Working fiddle: http://jsfiddle.net/SgubR/2/ (which also display the overflow: hidden along a floating element technique for creating a column. The latter needs a clearfix)
Table-cell in CSS uses any HTML element you want (section, div, span, li, whatever), its semantics is unrelated to table, tr and td elements used for table layout (except that the visual result is the same, that's what we want).
display: table is set on a parent
display: table-row may be used on an element in-between but if it works without it, fine
display: table-cell is set on each child
a width is set on none, some or all these "cells". Browser will adapt both to content and widths set in order to calculate their widths (and total width of parent, obviously)
table-layout: fixed will tell browsers to switch to the other table layout algorithm where they don't care about the quantity of content, only to widths set by CSS
vertical-align: top will be needed in most cases (but you may set other values, great for complex layouts)
margins aren't applied on "cells", only padding. Margins only apply on table itself. Though you still can separate "cells" with border-collapse: separate and/or border-spacing: 4px 6px
Compatibility: IE8+
Fallback for IE6/7 if needed is exactly the same as for inline-block
Longer explanations in previous answers: here and there with also the good old method of faux-columns (your design must be thought with this technique in mind)
Just add an oveflow to the right column and don't float it.
.right {
position: relative;
overflow: hidden;
}
This will make right to fill the rest of the width.
Something like this might work:
http://jsfiddle.net/PCvy9/2/
The main key of what you're looking for lines in the:
.right {
overflow: hidden;
background-color: #C82927;
}
This is due to something called the "block formatting context." Great reasoning and tutorial as to why here: http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats
However, their heights are not completely linked; in this example, your left side block's height would still need to be manually set (as it's a floated container)