1

I've read through some similar threads on this site and found some helpful tips, but I'm still having difficulty getting columns to work correctly in my CSS drop down menu. The test site is here: http://iphonebuy-host1.gaiahost.net/index.html

In part I'm using ideas from method 4 in this article - http://alistapart.com/article/multicolumnlists - however this is for XHTML and I'm using HTML, maybe that's causing my issue?

The main thing is the list items in the second column don't stick to the bottom of the header. According to the referenced article, setting a negative margin on .reset is supposed to bring the entire second column up where I want it, but only the header (which has .reset applied to it) is moving up.

I should say that you probably have to view my menu in Firefox to see what I'm talking about - so far it's even more messed up in Safari and I haven't even tried IE or Chrome.

CSS

/** top navigation menu **/
.topnav {
    list-style: none;
    background-color: #FFF;
    font: 1.313em arial, sans-serif;
    color: #0071BC;
    margin: -1.8em 0 1.2em 25em;
    text-align: center;
}
.topnav li {
    position: relative;
    display: inline;
    padding: 0 .5em 0 .5em;
    border: none;
}
.topnav a { 
    display: inline-block;
}

/** for drop-down menu **/
.topnav li ol {
    background: #fff;
    list-style: none;
    position: absolute;
    width: 15.5em;
    font: .8em arial, sans-serif;
    padding: 0 1em .5em .5em;
    margin-top: -.1em;
    left: -9999px;
    z-index: 200;
    -webkit-border-radius: 0 0 .5em .5em;
       -moz-border-radius: 0 0 .5em .5em;
            border-radius: 0 0 .5em .5em;
    -webkit-box-shadow:  0 3px 2px 1px #ccc;
       -moz-box-shadow:  0 3px 2px 1px #ccc;
            box-shadow:  0 3px 2px 1px #ccc;
}  
.topnav li li h1 {
    font: bold 1.2em arial, sans-serif;
    white-space: nowrap;
    margin: .5em 0 .5em 0;
}
.topnav li li h2 {
    font: 1em arial, sans-serif;
    white-space: nowrap;
}
.topnav li li a {
    white-space: nowrap;
    display: block;
}
.topnav li: hover ol {
    left: 0;
    margin-left: -.9em;
}
.topnav li: hover a {
    color: #99CCCC;
}
.topnav li: hover ol a {
    color: #0071BC;
}
.topnav li: hover ol a: hover {
    color: #99CCCC;
}
.topnav li li.column1 { 
    margin-left:  0em;
    width: 6.8em;
    float: left;
    line-height: 1.5em;
}
.topnav li li.column2 { 
    margin-left: 10em;
    width: 4em;
    float: left;
    line-height: 1.5em;
}
.topnav li li.reset {
    margin-top: -10.8em;
}

HTML

<div class="topnav">
  <ol>
    <li><a href="index.html" class="vertical-line">Home</a></li> 
    <li><a href="#" class="vertical-line">Get Quote</a>
      <ol>
        <li class="column1"><h1>Select phone:</h1></li>
        <li class="column1"><h2>CDMA</h2></li>
        <li class="column1"><a href="cdma3gs8gb">3GS 8GB</a></li>
        <li class="column1"><a href="cdma3gs16gb">3GS 16GB</a></li>
        <li class="column1"><a href="cdma4-8gb">4 8GB</a></li>
        <li class="column1"><a href="cdma4-16gb">4 16GB</a></li>
        <li class="column1"><a href="cdma4s16gb">4S 16GB</a></li>
        <li class="column1"><a href="cdma4s32gb">4S 32GB</a></li>
        <li class="column2 reset"><h2>AT&amp;T GSM</h2></li>
        <li class="column2"><a href="att3gs8gb">3GS 8GB</a></li>
        <li class="column2"><a href="att3gs16gb">3GS 16GB</a></li>
        <li class="column2"><a href="att4-8gb">4 8GB</a></li>
        <li class="column2"><a href="att4-16gb">4 16GB</a></li>
        <li class="column2"><a href="att4s16gb">4S 16GB</a></li>
        <li class="column2"><a href="att4s32gb">4S 32GB</a></li>
      </ol>
    </li>
    <li><a href="about.html">About</a></li>
  </ol>
</div>
Matt Coughlin
  • 17,170
  • 3
  • 42
  • 57
user2367680
  • 67
  • 2
  • 7
  • Please post a [jsFiddle](http://jsfiddle.net) – Jason Yaraghi May 09 '13 at 21:54
  • Your code floats the list items. The [method 4 example](http://alistapart.com/article/multicolumnlists) you linked to doesn't. That's the main difference. Best to stick to method 4 exactly, if you're going to use it. – Matt Coughlin May 09 '13 at 22:37
  • Is changing the HTML an option? The current HTML isn't well-suited for this type of layout (without the use of [CSS3 Columns](http://www.w3.org/TR/css3-multicol/)) (not supported by IE9 and earlier). – Matt Coughlin May 09 '13 at 22:38
  • @Adrift: I'm not using JS, is jdFiddle for other types of code also? – user2367680 May 10 '13 at 00:18
  • I added the float because method 4 was not moving the second column over at all - without the float it stays underneath column 1. Yes, I could change the HTML - do you have a suggestion @Matt Coughlin? – user2367680 May 10 '13 at 00:20
  • @user2367680: With an online demo site like [jsfiddle](http://jsfiddle.net), you can add HTML, CSS, and JavaScript. The CSS and JavaScript are optional. The "js" in "jsfiddle" doesn't have any special meaning :) – Matt Coughlin May 10 '13 at 00:25

2 Answers2

2

The code in the question floats the list items. The method 4 approach that it's based on doesn't. That one change prevents the approach from having the chance to work as intended.

In a case like this, it's best to either stay entirely consistent with the approach, or go in an completely different direction and do not imitate it at all. Getting caught in the middle -- inconsistently following the approach -- is likely to cause the most trouble.

Split the HTML into bite-sized chunks

You'll have a far easier time styling this if you change the HTML. Instead of putting everything into a single list and splitting the list up into 2 columns, try splitting the HTML into 2 separate lists.

It may require adding a few wrapper divs as well. Something like the following:

<div class="topnav">
  <ul>
    <li><a href="index.html" class="vertical-line">Home</a></li> 
    <li><a href="#" class="vertical-line">Get Quote</a>
      <div class="dropdown">
        <h1>Select phone:</h1>

        <div class="columns clearfix">   <!-- add a reliable clearfix -->
          <div class="column1">   <!-- floated left -->
            <h2>CDMA</h2>
            <ul>
              <li><a href="cdma3gs8gb">3GS 8GB</a></li>
              <li><a href="cdma3gs16gb">3GS 16GB</a></li>
              ...
            </ul>
          </div>

          <div class="column2">   <!-- floated left -->
            <h2>AT&amp;T GSM</h2>
            <ul>
              <li><a href="att3gs8gb">3GS 8GB</a></li>
              <li><a href="att3gs16gb">3GS 16GB</a></li>
              ...
            </ul>
          </div>
        </div>

      </div>
    </li>
    <li><a href="about.html">About</a></li>
  </ul>
</div>

Splitting the related parts of the dropdown into separate HTML elements gives you more flexibility with styling it.

And semantically, HTML of this sort is much better, because the h1 and h2 tags aren't being treated as if they're the same type of content as the specific models of phone. That helps with SEO and accessibility.

Matt Coughlin
  • 17,170
  • 3
  • 42
  • 57
  • Thanks for your suggestion @Matt Coughlin, I'll try this when I get home tonight. I didn't know what clearfix was so I looked it up and read that it is now better to use display:inline-block than float:left. Can I do that here? – user2367680 May 10 '13 at 13:14
  • @user2367680: You could probably manage with `inline-block`. But before deciding one way or the other, please take a look at the following answer, which compares using `inline-block` with `float` for layout purposes: http://stackoverflow.com/a/16469536/1306809 – Matt Coughlin May 10 '13 at 14:18
  • @user2367680: I did some additional research and updated the other answer I referred to: http://stackoverflow.com/a/16469536/1306809 – Matt Coughlin May 10 '13 at 16:42
  • Thank you, very helpful! I didn't realize inline-block had that issue. So is it sufficient to just add clear:both; or do I need something more complicated like the code found here - http://www.jqui.net/tips-tricks/css-clearfix/? Sorry, parts of CSS still really baffle me! – user2367680 May 10 '13 at 19:26
  • @user2367680: Either is adequate. Personally, I prefer clearfix, because it doesn't require adding additional HTML elements. For an explanation of both options, see the following discussion: http://stackoverflow.com/a/15787469/1306809 – Matt Coughlin May 10 '13 at 19:34
0

Use The following CSS

.topnav {
list-style:none;
background-color:#FFF;
font:1.313em arial, sans-serif;
color:#0071BC;
margin:-1.8em 0 1.2em 25em;
text-align:center;
}

.topnav li {
position:relative;
display:inline;
padding:0 .5em 0 .5em;
border:none;
}

.topnav a { 
display:inline-block;
}

.topnav li ol {
background:#fff;
list-style:none;
position:absolute;
width:15.5em;
font:.8em arial, sans-serif;
padding:0 1em .5em .5em;
margin-top:-.1em;
left:-9999px;
z-index:200;
-moz-border-radius:0 0 .5em .5em;
-webkit-border-radius:0 0 .5em .5em;
border-radius:0 0 .5em .5em;
-moz-box-shadow:    0 3px 2px 1px #ccc;
-webkit-box-shadow: 0 3px 2px 1px #ccc;
box-shadow:         0 3px 2px 1px #ccc;
}  

.topnav li li {

}

.topnav li li h1 {
font:bold 1.2em arial, sans-serif;
white-space:nowrap;
margin:.5em 0 .5em 0;
}

.topnav li li h2 {
font:1em arial, sans-serif;
white-space:nowrap;
}

.topnav li li a {
white-space:nowrap;
display:block;
}

.topnav li:hover ol {
left:0;
}

.topnav li:hover a {
color:#99CCCC;
}

.topnav li:hover ol a {
color:#0071BC;
}

.topnav li:hover ol a:hover {
color:#99CCCC;
}

.topnav li li.column1 { 
margin-left: 0em;
width:6.8em;
float:left;
line-height:1.5em;
}

.topnav li li.column2 { 
/*margin-left:10em;*/
width:4em;
float:left;
line-height:1.5em;
}

.topnav li li.reset {
margin-top:-10.8em;
}

And The HTML

<div class="topnav">
<ol>
<li><a href="index.html" class="vertical-line">Home</a></li> 
<li><a href="#" class="vertical-line">Get Quote</a>
  <ol>
    <li class="column1"><h1>Select phone:</h1></li>
    <div style="width:130px;height:auto;float:left">
    <li class="column1"><h2>CDMA</h2></li>
    <li class="column1"><a href="cdma3gs8gb">3GS 8GB</a></li>
    <li class="column1"><a href="cdma3gs16gb">3GS 16GB</a></li>
    <li class="column1"><a href="cdma4-8gb">4 8GB</a></li>
    <li class="column1"><a href="cdma4-16gb">4 16GB</a></li>
    <li class="column1"><a href="cdma4s16gb">4S 16GB</a></li>
    <li class="column1"><a href="cdma4s32gb">4S 32GB</a></li>
    </div>
    <div style="width:130px;height:auto;float:left">
    <li class="column2"><h2>AT&amp;T GSM</h2></li>
    <li class="column2"><a href="att3gs8gb">3GS 8GB</a></li>
    <li class="column2"><a href="att3gs16gb">3GS 16GB</a></li>
    <li class="column2"><a href="att4-8gb">4 8GB</a></li>
    <li class="column2"><a href="att4-16gb">4 16GB</a></li>
    <li class="column2"><a href="att4s16gb">4S 16GB</a></li>
    <li class="column2"><a href="att4s32gb">4S 32GB</a></li>
    </div>
</ol>
</li>
<li><a href="about.html">About</a></li>
</ol>
</div>

What I did over here is, put column1 inside a division and column 2 on a different division. Hope this will solve your problem. Thank you.

Chandan
  • 101
  • 1
  • It's invalid to put anything other than an `li` inside a `ul` or `ol`. The HTML won't validate (and might behave oddly in some browsers). – Matt Coughlin May 09 '13 at 22:43