treehouse : what would you like to learn today?
Web Design Web Development iOS Development

inline-block vs. float

  • I am trying to build a menu layout using a sprite with anchor tags. The problem I coming up with is should I use display:inline-block or display:block then use a floats?

    I know with inline-block there are issues with the margins. If there is a 'white space' between the two items, it css will add a 4px space. I can solve this problem using margin-right: -4px. I have noticed this works great in Safari and IE 8 but in firefox, the alignment is thrown off.

    Should I continue to try and tweak it or just switch to using blocks and floats?

    Thanks.
  • display: inline;
  • If you are using sprites you will need to declare a width and height. An inline element won't accept these values, I would recommend using display: block; and floating each anchor tag.
  • what are trying to show there? Joshua is right, an inline element will not take a width or height. You've set it to float which overrides any display value (inline, block, or inline-block (and others)). There is no need to set to block and then float. There was a need in IE6 to set the display to inline with floats only to kill the double margin bug, but if you know about the bug there are other ways to eliminate it anyway.

    @djpic, without seeing what you're trying to accomplish, I'd float the li (no need for display) and set the anchor to display: block
  • I'd rather use inline-block and get rid of that space, personally, as inline-block is like cheap floating without having to clear anything. but I guess the result is the same ultimately.
  • @wolfcry911: First I would like to address a question for you because you mentioned it. Why use a list for the menu? Everywhere I look I see this. Normally, I just use a div and anchor. What advantages are there to using a list for a menu? I take one is because you don't have set the display?

    @ChristopherBurton: I have tried inline on a menu awhile ago and of course it doesn't work as you can't specify a height or width.

    BUT I did play with the jsfiddle though and it did adjust the size of the li when I made the width and height 150px each? Not sure about that.

    @Johann: I am the same I think. For some reason I just think with inline-block, this is what it was designed to do and the float way is a hack (minus having to adjust the margins on the inline-block). But all I want is a way that works on the majority of browsers.

    @joshuanhibbert as seen this site before when it wasn't using any images. Now I have placed the images in.

    View current HTML & CSS

    Also, if there are any other suggestions about the layout, I am open to them.

    Thanks.


  • There's no need to use a list - it's just so commonplace that I expected its use. In fact, in another thread I mention that years ago (I'm dating myself) that it was rarely used (and even frowned upon by some). I do use the list myself - it gives plenty of 'hooks' for styling and scripting and some will argue it's more semantic. I personally don't think its any more or less semantic to use a list.

    Christopher's jsfiddle works because of the float - the display: inline is ignored. Display block would be ignored as well.

    I'm not sure why you think floats are hacks - they're not. I would use float here and not think twice about it. You can use inline-block, but the correcting for the space seems more of hack to me.

    Inline-block works and definitely has its place, but like all things, know its properties and when and where to use it. One thing to know about is the fact that IE 5 (dead),6, and 7 only accept inline-block on default inline elements (which would be fine here given anchors are inline).

    It appears you're just starting out and are learning through testing, which is great. Having and adjusting a live page is the best way to learn in my opinion. A few things of note:

    • Practice with sprites is great - but if this sprite is final, is it really necessary? Can't those be displayed and styled as ordinary text with css?
    • Content should be first, then style, then behavior. Semantically mark-up the content.
      • Your nav anchors should really contain the text shown in the images - even if you do ultimately use the image, you can just 'push' the text off screen. This will enable screen-readers and web-crawlers to read the page.
      • Divs and spans have no semantic value. They're important for structure but don't rely on them to contain content directly (your main content should be in p element within the div).
      • Empty divs and spans are generally frowned upon. There will be times when they're needed, but try your best not to use them (empty span for spacer is unnecessary).
      • Content in the footer image should be in the html. At the very least add it with an alt attribute to the image.
    • Images for design purposes only should really be put in the css as backgrounds, while those that are part of content should be in the html.
    • In your css, try to keep things simpler. Using a descendant id under another id is pretty 'heavy' for the interpreter (your nav ids). Usually a single id is enough - there will definitely be exceptions to this rule.
    • Try to use shorthand wherever possible (background, margin, padding, etc.)

  • Yeah, what @wolfcry911 said. (props for writing all that)
  • Very quickly, this is how I might mark-up that page:
    <body>
    <div id="header">
    <h1><img src="layout/header.jpg" alt="UBLOG - Universal Blogging Application"></h1>
    </div>

    <div id="mainmenu">
    <a href="#" id="Dashboard">Dashboard</a>
    <a href="#" id="MyBlogs">My Blogs</a>
    <a href="#" id="MyBlogList">My Blog List</a>
    <a href="#" id="MyAccount">My Account</a>
    <a href="#" id="SignOut">Sign Out</a>
    </div>

    <div id="content">
    <p>This is a test of the content to be added here!</p>
    </div>

    <div id="footer">
    <p>Copyright 2011 | Dale M. Picou, Jr. | The DjPic Network</p>
    </div>
    </body>
  • Semantically, I would disagree with that.
  • For djpic's sake, why don't you tell us why?

    I personally would use the new html5 elements (I may be mistaken, but I thought djpic said in another thread he didn't want to use the new elements yet). And I'd have an h1 above the content p, but assuming this is the front page, would still keep the h1 in the header for the site name. Again, this was a quick adaptation of the existing page...

    edit// just checked and now I don't believe it was djpic who didn't want to use the new elements...
  • @wolfcry911 - "I personally would use the new html5 elements"
    Exactly. We should all be using them.

    @djpic - Why would you not use HTML5 elements?
  • @wolfcry911 - that is a lot, thanks! You just answered and confirmed so many things that I have been wondering. But of course opened the door for more questions like most answers do. I have been designing for awhile (10+ years) just recently I have had a chance to revisit it all and break my old style habits of table based layouts. CSS was just getting started when I was playing with it but at the time, wasn't supported as well so just used it sparingly. Been focusing a lot on other items (networking, work, school, etc.) but now have an opportunity to get back in the game sort of speak.

    Actually, the person that showed me inline-block didn't like/understand float. I felt inline-block was tacky at first as I was using float before. It must just be the definition of inline-block makes it seem like it should be used. I will make the switch back to float (plus easier to use for me). I do have a question though about the float. So are you saying if I use float, then whatever is in the display is pointless? When you define float, does it auto-define it as a block?

    In reference to using lists for menus, I think I will stick with my current set-up for now. It works and don't really see an advantage to using lists.

    The sprites are there mainly because of the font and the dashed lines between each menu item. I know about font-face but of course it doesn't work in a lot of browsers and I wanted to stay as consistent as possible. My first build was actually ALL CSS before adding the images & sprites. I have reposted it here: Click Here for Version 1

    Amazingly, I did think of putting the actual text in the anchor tags but don't know how to 'push' / 'hide' the text.

    As far as the text in the content plane, that was there just as a quick placeholder as I was adjusting the margins therefore wasn't really formatted yet.

    Empty span tags were there for of course to place the spacer (as I used before in table layouts). But when I read what you wrote, I came to a realization that I could do the same thing I did with the content tab. Just export it as a 1px horizontal image and place it as a background. I am trying to adjust my mind set.

    With the footer, again used because I needed maintain the font type.

    I can see where the layout / design items makes sense to be placed as backgrounds and I like the idea. I could put the footer image element as a background along with the header. Then just export the logo as a standard image which would probably be best. The problem with the footer is I was going to make an image map so when I user clicks the copyright information, it would take them to my site.

    It is good to know about the descendant id's. I have wondered about that. I always want to know which way is more efficient (as you can tell from my previous post: Menus in CSS). I am all about optimizing for CPU and memory on both the client machine and server. Many times I have been told I shouldn't worry about things like that as the project / site won't be getting enough hits to matter. My response always is, "but what if it does?" I think it is best to get into the habit of optimizing the application now, and when a major project shows it self, it will just be second nature. I do believe more and more programmers are getting into the mind set of, "our clients have 4GB RAM and quad CPUs, who cares how much memory / CPU our application uses? They won't notice." Just because the power is there, doesn't mean you should write crappy code.

    What do you mean, shorthand? Are you talking about the naming convention or can a css file actually contain shorthand elements?

    @ChristopherBurton - I am open to using HTML5 elements as long as they 'fall back.' I am curious what HTML5 elements are we talking about here? I have looked at the HTML5 form elements, but nothing else. I will be doing a google search on these soon now that you mentioned them.

    @wolfcry911 - I will be working on making some of the modifications you have suggested. I will re-post here when the changes have been made.
  • Ok, I have now updated the layout with the suggestions (See Updates). I made the background for the menu items (instead of using the spans). Put the header as the background and extracted the logo to make it an image siting on top of the header background. Made the footer a background. I did combine these three items into one sprite. Also changed the menu to use block and float.

    New Issues:
    As you can see, the menu items are not aligned properly. For some reason they are not lined up with the menu div tag. Plus was trying to align them center, but that didn't work either (I am assuming because of the floats). Plus the space that is now between the menu and content blocks. On a plus side, it looks the same on firefox, safari, and IE.

    With the logo (and possibly menu items) should I use exact positioning? Right now I am using padding on the header. And with exact positioning, I could drop the menu sprite and align the items in relation to the background (which has the horizontal guides). But I still won't be able to have the font-face.

    Thanks for the input!
  • Update: I am now using absolute positioning for the menu items. It looks like it works and gets the items centered just the way I like them, but I still have a spacing issues, for instance, above the menu items and below the menu items. Any pointers?

    Update: I have removed the padding from the header and used absolute position on the logo. That fixed the issue with the spacer on the top of the menu. I then removed the paragraph tag from the content and that removed the space under the menu. The problem now is, if I put a paragraph tag in the content section, will that break it again?

    Update: I added the paragraph tag again, then change the padding (top & bottom) to 1px and now it works. Any explanation for this?
  • What are you trying to do, vertically align it? Also, there's no reason to use absolute positioning for your menu.
  • When you define float, does it auto-define it as a block?A special block, yes. The specs go into detail, but just know that any display value (but one) will be changed to block.

    In reference to using lists for menus, I think I will stick with my current set-up for nowThat's perfectly fine.

    The sprites are there mainly because of the font and the dashed lines between each menu item.The dashed lines could be borders and fonts and @font-face have come a long way. Even IE can use them. Besides, you're using a simple serif font that doesn't really call for anything special anyway. Here's a great link: Do websites need to look exactly the same in every browser?

    The problem with the footer is I was going to make an image map so when I user clicks the copyright information, it would take them to my site.One word: Why? Just use simple links and if you insist on using the images place them as backgrounds of or as img within the anchors.

    My response always is, "but what if it does?" I think it is best to get into the habit of optimizing the application nowAbsolutely, always use the best techniques possible and don't resort to lazy sloppy code - my thinking also.

    What do you mean, shorthand?I mean combine properties, like this:
    #content {
    padding-top: 1px;
    padding-right: 20px;
    padding-bottom: 1px;
    padding-left: 20px;
    }
    would become:<pre>#content { padding: 1px 20px; }</pre>the same holds true for margin and background and font.

    I am open to using HTML5 elements as long as they 'fall back.' I am curious what HTML5 elements are we talking about here?header, nav, section, article, aside, footer are the main elements - basically where all your id'd divs are could be replaced with new elements. Most browsers can deal with the new elements now. IE requires a simple 'shiv', or small bit of javascript in order to style the new elements. I'd consider it safe for most any site now, certainly any site anyone on these forums (myself included) are developing.

    I never got to see the update with floats, so can't really comment on those now. It's okay that you've used absolute positioning on the logo and nav. It works and is acceptable, but don't fall into the trap of thinking its the best thing since sliced bread and use it everywhere. A layout built solely on AP will fall apart and become harder and harder to maintain as you add content. I personally would still use floats.

    The spacing issues are caused by a couple of different things. Learn the box model - padding and borders are added to width and height, so for example if you wanted an element to be 100px tall with a top and bottom padding of 10px each, the height would need to be 80px. The spacing under the nav was caused by the top margin of the p (or any element) - its known as margin collapse and is normal. A top padding or border on the parent gives the margin something to 'push' against. Another way to adjust things would be change its formatting context, but I don't want to confuse you at this point. Still another thing that may have been done was to put the #content background on a wrapper div (which you currently don't have, but doesn't matter either way).

    In looking more closely at the design and code, I think I would place the nav inside the header. It seems to make sense and would make styling easier. Regarding the spacing of the floats and the background image - I'm sure things could have been adapted to work, but you've switched to AP.
  • I will upload the float version again in a few hours.
  • djpic, here's another example page. I'm not insisting you do it this way, but just wanted to show you what was possible. I only used one background image (and could eliminate that too with some fancy pseudo element styling). This will work in most modern browsers including IE 9 and 10. For older browsers, you could just let extra design elements go (the box-shadow) or feed stylesheets to IE to accomodate and use browser prefixing for further css3 support. You should also throw in the shiv for IE...
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>CSS Test AI Layout</title>
    <style type="text/css">
    body {
    margin: 0;
    padding: 0;
    background: #9f947f url(layout/main_background.jpg) repeat-x;
    }

    #wrapper {
    width: 800px;
    margin: 16px auto 0;
    padding: 0;
    border: 1px solid #000;
    background: #fff;
    box-shadow: 0 0 8px #000;
    min-height: 500px;
    }

    header {
    background: #d6af8e url(layout/xxhorizontals.jpg) repeat-y top center;
    height: 129px;
    position: relative;
    }

    #logo {
    margin: 3px 0 0 5px;
    }

    nav {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: #000;
    height: 30px;
    }

    nav a {
    float: left;
    width: 159px;
    color: #eee;
    text-decoration: none;
    font: small-caps 16px/30px capitals, georgia, serif;
    text-align: center;
    border-right: 1px dashed #eee;
    letter-spacing: .04em;
    }

    nav a:last-child {
    border-right: 1px solid #000;
    }

    nav a:hover {
    color: #c4bd4b;
    background: #016938
    }

    article {
    padding: 10px;
    }

    article h1 {
    margin: 5px 0;
    color: #016938;
    }

    footer {
    width: 800px;
    margin: -5px auto 0;
    text-align: right;
    font-family: capitals, georgia, serif;
    font-variant: small-caps;
    font-size: .8em;
    }

    footer a {
    text-decoration: none;
    color: #000;
    }
    </style>
    </head>

    <body>
    <div id="wrapper">

    <header>
    <img src="layout/logo.jpg" id="logo" alt="uBLOG - Universal Blogging Application" height="90" width="266">
    <nav>
    <a href="#" id="Dashboard">Dashboard</a>
    <a href="#" id="MyBlogs">My Blogs</a>
    <a href="#" id="MyBlogList">My Blog List</a>
    <a href="#" id="MyAccount">My Account</a>
    <a href="#" id="SignOut">Sign Out</a>
    </nav>
    </header>

    <article>
    <h1>This is the topic of this page</h1>
    <p>This is a test of the content to be added here!</p>
    </article>

    </div> <!-- end of wrapper -->

    <footer>
    <p>Copyright © 2011 | Dale M. Picou, Jr. | <a href="http://www.djpic.net/&quot; target="_blank" title="The DjPic Network">The DjPic Network</a></p>
    </footer>

    </body>
    </html>
  • @ChristopherBurton - I am trying to center the menu. Why should I not use absolute position?

    @wolfcry911 - That design looks perfect, but of course only in Safari on my machine. I am running a VM with IE 8 and it looks like crap (no offense). In firefox, does a little bit better, but the menu is off along with the copyright notice (I do have firefox version 3.6 and they are out with 6? I have only had this computer for around a year). Once upgraded to version 6, it looked fine. I don't know if it is more of the HTML5 tags or the CSS3 that is messing with the look in IE8. I know that IE8 is old but if you look at companies and such, there still is a lot of people using it. Plus the people like me that didn't update their browser (safari is my primary). I would like to keep it consistent in all browsers without having to format for every single browser. Personally I think it is ridiculous that you have to do that. This is why I have used table layouts for so long. I can whip out a table layout in under than 30 minutes for this site and it would look identical on ALL browsers but that defeats the purpose of me doing this (and is now frowned upon). I want one constant way that will look and work the same in all browsers from the last 5-6 years. Just call me crazy! I did play with the shadow property a few times in the first revision and didn't mind missing it in the other browsers. Things like that I can live without, but when a menu goes crazy or a design isn't aligned correctly, then it just drives me nuts! Don't get me wrong, I do love the way you did it and really that is the way it should be done. I will keep it as an example (wolfcry911 example) and posted it for any others that would like to take a look. I just think we need to wait another 2-3 years to be able to use that and not have to worry. IE is really holding everyone back.

    I have posted the old version before I made all the corrections: click here for version 2

    Of course, I found the issue with the spacing on the top of the menu had to do with the header padding. I did notice you used padding / margin on the logo itself, so that might also be another route instead of absolute positioning. The spacing on the bottom of the menu was an issue as well (between the menu and the content). That again was fixed the minute I put the padding; I am sure because of the reasons you stated. The only thing that was stopping me from using float from that point on was centering the whole menu. The nav in your example was only 800 wide which you were able to do because of the wrapper was providing the shadow / glow. The background image of mine is providing the shadow leaving 10px on either side to be filled (and the spacers soon). Without centering the entire menu, it will stay to full left putting it out of alignment.

    With the collapsable css, I tried changing the background element and of course it broke in IE8 so I think I will leave it alone for now.

    With the padding, what you are telling me is if I define say a div with the height of 100px and width of 100px, when I add padding of 10px to all sides, the height will then be 120px and width then would be 120px? I understand where this is going but I assumed it wouldn't add to the total, would just move in from the outside. For example, the same situation, the div tag would still be 100 x 100 but the area I could type in would be 80 x 80. The same with the border. 100 x 100 with a 1px border would equal 102 x 102 (on the outside) or would the 1px border be on the inside of the div?

    With absolute positioning I know that could turn bad. I just figured the menu and header is not going to change much within it's own div. I would not do that for any content on the site and if I do, it would be relative to a parent.

    I am not sure with the nav / menu (which is better, nav or menu?) in the header. How would you make sure it was aligned to the bottom? I did see in your example that you used the absolute positioning to position the nav at the bottom of the header I think?

    With the image map, I thought that would be pretty much the same thing (easier) then creating an anchor and then using absolute positioning to place the anchor over where I need it to be clickable. But now that the footer is in the background, will do it with AP?

    Again, thank you for all this help. I have been off of work for a week, so this stuff has been keeping me occupied.
  • Wow...that is like a wall of text!
  • Use margin: 0 auto;
  • I have tried that on the #mainmenu but doesn't work.
  • add this at the very top of your stylesheet
    * {margin: 0; padding: 0;}
  • still nothing.
  • where did you add margin: 0 auto to?
  • #mainmenu
  • I added that to the wrong discussion


    Add margin: 0 auto; to the nav element.
  • I am not using a nav element. I am using a div element with an ID of mainmenu haven't tried switching to any HTML5 tags yet.
  • did you remove the absolute positioning?
  • yes, I am changing it on the version without ap.
  • Can you give me a link to the version without AP?
  • @djpic - What font are you using for the menu?
  • The text font or the font in the sprite?

    The anchors have text in them but it is just pushed off the screen. The text you are seeing is from the sprite image. The font name is: Capitals
  • My example, as mentioned, did not include the shiv for IE. Do me a favor and add this little bit to that page between the footer a style in the head and the closing head tag:
    footer a {
    text-decoration: none;
    color: #000;
    }

    article, aside, figure, footer, header, hgroup,
    menu, nav, section { display: block; } /* defaults for html5 elements */

    </style>
    <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    </head>
    This will correct IE6, 7, and 8 as well adjust older Firefox, etc. That's it - that's all that's needed!

    Now back to your page...
    You really don't need to center the menu. What you need is to have it start 10px from the left to compensate for the shadow. Simply put a left and right margin on #mainnav #mainnav { margin: 0 10px; } /* <-- shorthand! */
    You've already discovered the padding problems so all that remains is the vertical positioning of nav. There are a couple ways of approaching it. I personally like the way I used in my example (using absolute positioning of the nav and floating the anchors within). That had the nav inside the header and was positioned to the bottom of the header. Your current float code has the nav outside of the header, so you could position it in relation to the body, or use a negative top margin to pull it up - either will work. Try the negative top margin, so now the #mainnav margin looks like
    #mainnav { margin: -30px 10px 0; } /* <-- more shorthand! */
    So, to fix all the problems with the float page, all I had to do was change height of header to 126px and its padding to 20px 15px 0; add margin of -30px 10px 0 to #mainnav, and add 1px padding to #content. Sure beats re-doing the entire page with a different method ;)
  • This could be done with CSS alone without absolute positioning and with @font-face. But hey, whatever way you think is best.
  • @wolfcry911 - Yep, that fixed it on your layout. Also, I have seen a comment formatted like that before. That is just like an HTML if statement? What is the official name of those so I can google it? I do like the full CSS layout better the only thing holding it back was the browser compatibility, but with that shiv fix makes it worth it. I did notice that IE 8 put the dashed line at the end of the menu as well (after SignOut). Does that have something to do with IE8 not supporting last-child I take it? It is kind of funny how I started wanting to do the whole thing using CSS and then went to using images, and now I am back to using CSS. The only thing thing really that is an image is the logo. If you don't mind, I will use more of what you did in your example instead of using all those sprites and such? I am also amazed with the matching the font type so well. is the 16px/30px is defining the size of the lower case caps and the upper case caps (and how did you know it was the capitals font?

    @ChristopherBurton - I know it can, that is what @wolfcry911 did in his example.
  • I still see position:absolute; so I would disagree. But everyone has different opinions as to what absolute positioning should be used for. Since you want the menu contained within the flow of the page, I would not use absolute positioning. That is my opinion.
  • I must not have uploaded it, just did again. I didn't want to use AP but didn't know of a way to do it at the time, now @wolfcry911 said to just change the padding, which I did and now it is fine.
  • Awesome
  • I have seen a comment formatted like that before. That is just like an HTML if statement?
    It's a conditional comment - the defacto standard for feeding IE fixes for several years now.

    I did notice that IE 8 put the dashed line at the end of the menu as well (after SignOut). Does that have something to do with IE8 not supporting last-child I take it?
    Yes, that's correct. I probably should have put the border on the left and used first-child to remove it from the first. IE 7 and 8 understand first-child, but not last (IIRC). You could feed IE 6 ( 7 and 8 ) a fix with conditional comments. Or you could class the first or last anchor and target it that way.

    The only thing thing really that is an image is the logo.Which is content, so that is good. But, I don't want you to think that background images in css are bad - they're not. Sometimes, however, it's just quicker, easier, lighter to use straight css.

    If you don't mind, I will use more of what you did in your example instead of using all those sprites and such
    I don't mind at all. I was just hoping to help you out.

    Is the 16px/30px is defining the size of the lower case caps and the upper case caps?
    No, the 16px is font-size and the 30px is line-height - which centers the font vertically within the nav - more or less. It will be 1px off from browser to browser because of the way fonts and inline boxes work. You could also not set the line-height and use top padding to center vertically. The upper and lower case caps was achieved with the font-variant: small-caps (which is in the font shorthand rule).

    and how did you know it was the capitals font?
    ;)
    Capitals should be available to anyone with MS Office installed (PC or Mac) which is a very large percentage of probable viewers. I set a fallback to Georgia if Capitals is not available and then to serif if Georgia is not available - you can change or add as many fallbacks as you like. So most of the visitors will see it the way you intended and small percentage will see something very close (and will have no idea its not your first choice). You could also use @font-face, like Christopher mentions above, to pretty much guarantee that everyone sees the same font.
  • Here's a change so that IE 7 and 8 (screw IE 6) don't have the dashed border at the end. I changed the first-child to not have a border and increased its width 1px, so that on hover you wouldn't notice the 1px offset (that could be seen when I changed the border to black). Again, this is just to show you how much is possible with css and how things can be tackled in many different ways.
    nav a {
    float: left;
    width: 159px;
    color: #eee;
    text-decoration: none;
    font: small-caps 16px/30px capitals, georgia, serif;
    text-align: center;
    border-left: 1px dashed #eee;
    letter-spacing: .04em;
    }

    nav a:first-child {
    border-left: none;
    width: 160px;
    }