CSS - floating LIs - bigger content messes up the next row - css

<style>
ul{margin:0px;padding:0px;}
ul li{margin:0px 5px 5px 0px;padding:0px;list-style-type:none;float:left;}
</style>
<ul class="clearfix">
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
</ul>
The first li contains more content than the rest.
So, I have the following problem:
problem http://img830.imageshack.us/img830/240/problemc.png
But how do I move the next row down, so it looks like that:
want this http://img440.imageshack.us/img440/9750/solutionm.png
I tried using display:inline-block; instead of float:left; for the lis, which works, but I'd still rather use float:left; over inline-block.
Any ideas on how to do this?
Solution for IE:
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/

The best solution is to use a little-known display style called table-cell.
I've had to do this a few times. Here's how you do it:
/* -*- CSS -*- */
ul li .wrapper
{
display:table-cell;
width:100px; /*replace here*/
min-height:100px;/* " " */
}
ul li
{
float:left;
display:inline-block;
}
ul
{
display:table;
}
...
<!-- HTML -->
<ul>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
<li><div class="wrapper">my-content</div></li>
</ul>
How this works:
When the parser sees that there's a UL object, it treats it like a table instead of a list. This gives you the distinct advantage that you're beginning to /act/ like you're working with tables (but you're not!)
The rule then runs against the wrapper class -- this creates a "Table cell". We don't want to put it in the li because OTHERWISE the li will act as the table cell. This is kinda bad. the work around is that your li is actually aligned left. There's some argument whether or not is a good idea to do it this way -- this is the "Most Effective" because it forces the box model to comply. Its fugly, I know.
the REASON its bad for the li to be treated like a table-cell is that it won't wrap. The reason it wont wrap is that table-cells aren't supposed to wrap.
There is ONE other solution that might work, however I haven't tested it.
/* -*- CSS -*- */
ul li { display: inline-block; float:left; min-height:200px;width:200px; }
Its not as ugly, but it should work by making the box model force the alignment as well.

First of all: Are you sure you're using the right markup? A list generally doesn't end up to look like that.
Second. Do you know how many items you will have on a row? In your image they seem to have the same width. If you know that you can add clear:both; to the forth li (and other you may need) and force it down. This would be the only way to do it with left floating lis.

You can't do this using only float:left; the blocks just fall into place where they fit as your first example shows. If you intend for your content to always display in three columns, you could programmatically clear the float on the first item in each row.

Related

Align first line to the left, while other to the right using CSS

Is it possible to have the first line of text (or inline-blocks) aligned to the left, while the next one to the right using only CSS? I'm sure it can be done using JS, but am looking for a cleaner and simpler solution.
I have this navigation bar (which is a <ol> in the markup). It's usually one-line long, but recently we got a case, when it's grew long enough, so that it broke to the second line. Below is the photo of that. What my boss asked me to do is align the second line to the right, while keeping the first intact.
Now it looks like that:
What I'm aiming for is this (I'd then make some fixes to make it look prettier than on the picture below):
The markup. All li items are inline-blocks, but I could change that.
<ol class="phase-labels">
<li class="phase-label phase-current">Company</li>
<li class="phase-label phase-inactive">The Policy</li>
<li class="phase-label phase-inactive">Property Insurance</li>
<li class="phase-label phase-inactive">Additional Clauses</li>
<li class="phase-label phase-inactive">Public Liability</li>
<li class="phase-label phase-inactive">Public Liability Additional</li>
<li class="phase-label phase-inactive">Employers Liability</li>
<li class="phase-label phase-inactive">Quotes</li>
</ol>
You could try using direction propertie + text-align:justify to fill up entire first-line.
What does this involve? :
it reverse the reading direction of li (as inline-boxes) and
punctuation.
if only one line , lis stand towards right.
DEMO
Basic CSS
ol {
display:block;
position:relative;
direction:rtl;
text-align:justify;
}
Note: too bad text-align cannot be overwritten through the pseudo class :first-line.
You have the display:flex propertie too. DEMO
Basic CSS :
ol {
display:flex;
flex-wrap:wrap;
justify-content:flex-end;
}
I did misunderstand what he was looking for sorry everyone, why not try this. I think the following css should work.
ol{
float: right;
}
ol li{
float: left;
}
This answer is based around the idea that if the nav bar has exceeded the parents width, then it's float won't necessarily matter, but aligning everything to the right ensures it positions where you want. And floating the list items to the left, allows everything to be displayed in the proper order

CSS3 selectors - select very first item or item after

Let's say a have the following code:
<nav id="main-navigation">
<ul>
<li>Link 1 Level 1</li>
<li>Link 1 Level 1</li>
<ul>
<li>Link 1 Level 2
</ul>
</ul>
</nav>
And now I want to to set first ul's height to 100px and second ul should be 300px.
When I try
nav ul {
height: 100px
}
Second ul also inherits this value.
I was trying "~", "+", ">", first-childs etc. but don't know how to do that, even with documentation.
Is there a good explained (preferably with demos/screens) guide to new css3 selectors? W3 Table is too nerdy for me.
Thanks!!!
Just select any ul that is a descendant of ul and give it that style, if you will only have 2 layers of <ul>s. No need for any special CSS2/CSS3 combinators since <ul> cannot directly contain <ul>, plus you don't have to worry about IE either.
nav ul {
height: 100px;
}
nav ul ul {
height: 300px;
}
To select direct children of an element, and not any descendant, you should use the > syntax. In your case (after you put the second ul inside a li) you need:
nav > ul {
height: 100px;
}
nav > ul > li > ul {
height: 300px;
}
Extra: It doesn't really make sense to have a 300px item inside a 100px item. Why do you want that?
Another extra: Try to read the w3c docs, it will save you some time in the long run. What you don't understand you can always ask on SO.
Firstly, how imporant is browser compatibility to you? All of those selectors you mentioned have issues in various versions of IE (IE8 is obviously better than IE7, but even IE8 is missing a lot of CSS selectors)
Simple nested selectors (ie just a space between the CSS names) will work for you - although as you say, setting nav li {height:100px;} sets it for all the LIs, you can override that with nav li li {height:300px;} to set the inner one back the way you want it.
If you want to use the 'correct' selectors, the one you want is >.
nav>ul>li {
height:100px;
}
This will only affect the outer LI elements, not the inner one. However as I say, it won't work in older versions of IE (fortunately it does work in IE7 and up, so it's only an issue if you want to support IE6).
You say that you've found the various selectors quite hard to grasp. I recommend you visit Quirksmode. For a start, it's got a very handy compatibility chart showing which browsers support which selectors, but it's also got excellent examples of how each selector works, which should help you understand them a bit better.

How to make resizable li elements with CSS only

Scenario: I have an unordered list < ul > of width (lets say 200px) with four < li > elements that are sized equally. Therefore each should be 50px. When I add a 5th < li > element each width should re-size to 40px. If I change the width of the < ul > to 500px with 5 < li > elements, each < li > element should be 100px.
Is this possible with only CSS? If yes, how is it implemented?
Currently, I have a solution that meets the above requirements but it includes jQuery to re-size the < li > elements based on mathematical calculations.
Thanks for the attention.
Aparently you can fake tables like here, but I am not sure if this works in all browsers(edit: it works on winxp ie8, chrome 7, firefox).
<div id="menu">
<ul>
<li>
...
</li>
<!-- other list items -->
</ul>
</div>
#menu {
display: table;
}
ul {
display: table-row;
}
li {
display: table-cell;
}
Also example on fiddle.net here
Your question doesn't completely make sense to me. If you leave the widths off, the list will be as wide as it needs to be. But here's a crack at your question:
<style type="text/css">
ul
{
width:500px;
}
li
{
width:100px;
}
</style>
<ul>
<li>1. one</li>
<li>2. two</li>
<li>3. three</li>
<li>4. four</li>
<li>5. five</li>
</ul>
Using CSS expressions it is possible, but CSS Expressions come with a very heavy performance penalty. JavaScript (and jQuery for that matter) is the appropriate tool to use to create the effect you want.
CSS should only be used for styling, HTML should only be used for structure, and JavaScript should be used whenever you want to create dynamic content.
Until such a time as browsers implement the calc(), min() and max() functions this isn't possible outside of scripting (either server-, or client-, side) or using a table.
Currently, and surprisingly (perhaps only to me), neither Firefox, Webkit or Opera support calc() function, not even with the various flavours of vendor prefix.
That said, one day something like the following might work (but not today, sadly):
ul {
counter-reset: numListItems;
width: 60%;
}
ul li {
counter-increment: numListItems;
width: calc(100%/numListItems);
}
But, obviously, for that to work browsers would need to implement some form, and understanding, of variables within the scope of calc(), which doesn't appear to be necessarily on the road-map (I'm not sure that the counter() is, or is intended to be, interoperable with the calc()).

Capture a literal in css

I have several NAV Bars. Each NAV Bar is of the pattern;
a | a
such that where the literal "|" occurs, it's always has a sibling a on the left.
where a is an html anchor element and "|" is a literal separator of interest.
What css can I use to capture that literal "|"? The idea is that I want to set it display:None for print media.
Thanks for any help.
My recommendation would be to use an unordered list
<ul class="myNav">
<li><a>My Nav</a>
<li class="last"><a>Another nav</a>
</ul>
And then float the list items left, and then put a border on one side of each list item. Now the CSS below isn't exact, but it gives the general idea
.myNav li {float:left;border-right:1px solid black;}
.myNav li.last {border-right:0}
That should look similar, and be 100% css for seperators.
CSS selects html elements. | is not an html element, it's a text node, you can't access it. However, you can probably use background images on the anchors instead, and make them the divider. That or wrap spans around the divider and target them.
<span class="divider">|</span>
or
#nav a { background:url(/images/divider.gif) no-repeat top left; }
#nav li.last a { background-image:none; }
I didn't mention borders because they would rely on the height of the element being applied to and assumed you wanted more control, more customized but you could of course use those.
You need hooks to select anything with CSS. If the "|" characters aren't marked up in some way, you can't select them. Put them in span elements, or, better yet, replace them with background images, and define your navigation as a real list.
Yeah, you'd have to surround them, with say a span element. Then give those spans a class of "pipe" or something. Then use the CSS class "pipe" to set the display to none for printing.
You could position the parent element outside but the a elements inside the viewport. Something like this:
div {
position: relative;
top: -10em;
}
div a {
position: relative;
top: 10em;
}
But you should better use a list for your navigation and format that:
<ul id="nav">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
#nav, #nav li {
list-style: none;
margin: 0;
padding: 0;
}
#nav li {
float: left;
}
If you just need a simple text divider, using the content property is a fast, semantic way to achieve this.
<div id="nav">
Nav1
Nav2
</div>
#nav a + a:before { content: '|'; }
Note that content and adjacent sibling selectors (the + in the selector above) don't work in older browsers like IE6, but since this is just a divider, it shouldn't be a huge concern.
Edit: Note that this will make the | appear inside the link, so you should use a list instead (that is also the correct way to mark this up anyway).

How can I manage this nested markup and CSS to keep things simple and easy to work with?

I have the following markup that is used to produce a pop-up style mega-menu (the .column div is there to allow multiple columns within each popup, though the example below only has a single column)...
<ul id="mainmenu">
<li class="mega">
<h2>Menu 1</h2>
<div class="submenu col1 leftmenu">
<div class="column">
<ul>
<li><h3>Sub Menu Heading</h3></li>
<li><a class="hilight" href="#">Do Something</a></li>
<li><a class="hilight" href="#">More great stuff</a></li>
<li>Another Item</li>
</ul>
</div>
</div>
</li>
<li class="mega">
<h2>Second Menu</h2>
<div class="submenu col3 leftmenu">
blar blar blar
</div>
</li>
// more menus here
</ul>
As this nests quite deeply with quite a few similar tags (<li> <a>) I end up needing a fairly horrible list of selectors to style it in css, eg.
#mainmenu li h2 a {}
#mainmenu li.mega .column li h3 a {}
Can anyone suggest any improvements to the markup so that it would be simpler to target with CSS and jQuery?
If it were me, I'd put nicely targetable classes on the final entities in question, and change
#mainmenu li h2 a {}
to
#mainmenu .section {}
and
#mainmenu li.mega .column li h3 a {}
to
#mainmenu .subsection {}
and whatnot.
Personally I think your html looks good, it's not plagued with endless ids and none of the classes seem redundant or useless.
If you don't ever use an h3 anywhere but inside an li, inside a column, inside a parent li then you could do: #mainmenu h3 a. I really think you can just be less explicit in your selectors.
I try to really utilize unique html tags so that all I need is an id on the top-most element and a few classes beneath if needed.
You could always use more specific selector names. Instead of:
#mainmenu li.mega .column li h3 a {}
and
<ul id="mainmenu"><li class="mega"><div class="column"><li><h3><a>
use
h3.mega_column a {}
and
<ul id="mainmenu"><li class="mega"><div class="column"><li><h3 class="mega_column"><a>
Not without seeing the rest of your CSS really, but I think your motivation is wrong. You should aim for your mark-up to reflect exactly what content is required. If this thing needs to be defined as separate from that thing they need to exist as different elements, if not, not. Separate concerns and don't even think about the CSS until your mark-up is as it needs to be.
I will say that it looks like it's possible you could collapse div.column and the ul child into just ul.column and the anchor in the h2's could possibly be moved inside the div.submenu's and given a "header" class for example.
Aside from making sure that your structure is really fitting the semantics of your content and not just there for design reasons, there are a few things I can suggest:
You don't need to wrap <ul> in a <div> if there's nothing else in the div. They're both block-level elements and you could write <ul class="column"> and save yourself some unnecessary markup. It's redundant as-is.
You might be able to simplify your CSS a lot if you're not using class names to mean different things in different places. For example, if you only use the "column" class in under #mainmenu .mega then there's really no need to specify it every time. Just saying .column h3 a will get there just the same.
If you want simplicity in jquery you could also take advantage of the CSS3 selectors like :not() to sort things out for you. For example instead of $("#mainmenu li.mega .column li") you could instead do $("#mainmenu li:not(.mega)")
Those are my thoughts.

Resources