Advantages of using display:inline-block vs float:left in CSS - css

Normally, when we want to have multiple DIVs in a row we would use float: left, but now I discovered the trick of display:inline-block
Example link here.
It seems to me that display:inline-block is a better way to align DIVs in a row, but are there any drawbacks? Why is this approach less popular then the float trick?

In 3 words: inline-block is better.
Inline Block
The only drawback to the display: inline-block approach is that in IE7 and below an element can only be displayed inline-block if it was already inline by default. What this means is that instead of using a <div> element you have to use a <span> element. It's not really a huge drawback at all because semantically a <div> is for dividing the page while a <span> is just for covering a span of a page, so there's not a huge semantic difference. A huge benefit of display:inline-block is that when other developers are maintaining your code at a later point, it is much more obvious what display:inline-block and text-align:right is trying to accomplish than a float:left or float:right statement. My favorite benefit of the inline-block approach is that it's easy to use vertical-align: middle, line-height and text-align: center to perfectly center the elements, in a way that is intuitive. I found a great blog post on how to implement cross-browser inline-block, on the Mozilla blog. Here is the browser compatibility.
Float
The reason that using the float method is not suited for layout of your page is because the float CSS property was originally intended only to have text wrap around an image (magazine style) and is, by design, not best suited for general page layout purposes. When changing floated elements later, sometimes you will have positioning issues because they are not in the page flow. Another disadvantage is that it generally requires a clearfix otherwise it may break aspects of the page. The clearfix requires adding an element after the floated elements to stop their parent from collapsing around them which crosses the semantic line between separating style from content and is thus an anti-pattern in web development.
Any white space problems mentioned in the link above could easily be fixed with the white-space CSS property.
Edit:
SitePoint is a very credible source for web design advice and they seem to have the same opinion that I do:
If you’re new to CSS layouts, you’d be forgiven for thinking that
using CSS floats in imaginative ways is the height of skill. If you
have consumed as many CSS layout tutorials as you can find, you might
suppose that mastering floats is a rite of passage. You’ll be dazzled
by the ingenuity, astounded by the complexity, and you’ll gain a sense
of achievement when you finally understand how floats work.
Don’t be fooled. You’re being brainwashed.
http://www.sitepoint.com/give-floats-the-flick-in-css-layouts/
2015 Update - Flexbox is a good alternative for modern browsers:
.container {
display: flex; /* or inline-flex */
}
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
More info
Dec 21, 2016 Update
Bootstrap 4 is removing support for IE9, and thus is getting rid of floats from rows and going full Flexbox.
Pull request #21389

While I agree that in general inline-block is better, there's one extra thing to take into account if you're using percentage widths to create a responsive grid (or if you want pixel-perfect widths):
If you're using inline-block for grids that total 100% or near to 100% width, you need to make sure your HTML markup contains no white space between columns.
With floats, this is not something you need to worry about - the columns float over any whitespace or other content between columns. This question's answers have some good tips on ways to remove HTML whitespace without making your code ugly.
If for any reason you can't control the HTML markup (e.g. a restrictive CMS), you can try the tricks described here, or you might need to compromise and use floats instead of inline-block. There are also ugly CSS tricks that should only be used in extreme circumstances, like font-size:0; on the column container then reapply font size within each column.
For example:
Here's a 3-column grid of 33.3% width with float: left. It "just works" (but for the wrapper needing to be cleared).
Here's the exact same grid, with inline-block. The whitespace between blocks creates a fixed-width space which pushes the total width beyond 100%, breaking the layout and causing the last column to drop down a line.
Here' s the same grid, with inline-block and no whitespace between columns in the HTML. It "just works" again - but the HTML is uglier and your CMS might force some kind of prettification or indenting to its HTML output making this difficult to achieve in reality.

If you want to align the div with pixel accurate, then use float. inline-block seems to always requires you to chop off a few pixels (at least in IE)

You can find answer in depth here.
But in general with float you need to be aware and take care of the surrounding elements and inline-block simple way to line elements.
Thanks

There is one characteristic about inline-block which may not be straight-forward though. That is that the default value for vertical-align in CSS is baseline. This may cause some unexpected alignment behavior. Look at this article.
http://www.brunildo.org/test/inline-block.html
Instead, when you do a float:left, the divs are independent of each other and you can align them using margin easily.

Related

Transfer block in table-cell on a new line

I’m writing a template for marking on flex/box. And faced with the problem of emulation of some properties. At the moment, I decide them on JS. What complicates code.
So I decided to try to use the property of table-cell for child elements whose parent has the property display: block. Yes, it’s not right, but it works!
When I’m trying to break the table-cell elements to strings, I ran into a problem. And that’s how I tried to solve them:
If the child blocks table-cell overflow the parent horizontally, then
the following blocks are not transferred to the new line. And it is
logical. Example: Nowrap in link.
If I use the cancel flow, I lose equal to the width of columns for the element to be wrapped to the next line. So, this method only works for IE9+. I’m willing to drop IE7, but not ready to abandon IE8. Example: Wrap nth-of-type in link.
If I use the blocks which separate the table-cell on the line, everything becomes fine! But this complicates the CSS and JS code. Example: Wrap with break elements in link.
Example: http://codepen.io/anon/pen/GmgXmO
What ways to break table-cell can be applied, besides the above described options?
An example of a 12 column layout, fix the problem of calculation of the width percentage: http://codepen.io/anon/pen/PmwRvK
In order to make it clear why I do this.
I will be glad to hear your answers! And excuse me for my bad English.
P.S.: Ignore the strange size of the width in percent. It is calculated
according to the formula:
(100 * element.clientWidth / element.offsetWidth).
The smaller size, so it is more. Funny. This rule is applicable only to
the parent display: block containing the child elements display: table-cell

Why bootstrap uses floating elements to construct Grid System? [duplicate]

I was tinkering with custom grid and wanted to see how other people have created their grid-systems. Since twitter's bootstrap seemed to be so popular i've looked at its code. Now i wonder why are they using floats? I would use display: inline-block; html elements have either display: inline; or display: block; i would try to avoid floats. But for some reason bootstrap creators decided to use floats. first i was thinking they used them to have backward compatibility since ie6 does not support display: inline-block; and ie7 supports it only on elements with display: inline; by default. But ie6 more or less out of the game and since they use micro clearfix hack which uses *zoom: 1; to target ie6+ IMO they could replicate the same display: inline-block; with *display: inline; *zoom: 1; So the final Question Why Floats Over Display Inline Block? Are there any issues they tried to solve i didn't mentioned above?
Inline blocks are white-space aware, have an auto width of the actual content and stacks in the order they have in HTML. Floats aren't but require a clearfix method and are based on block elements. These elements have auto width on the available space horizontally. Purely semantically, inline-blocks are less semantic since the white-space aware format and importance of order. But looking at it purely in a functional way, both just aren't made for a grid. And if it wasn't for pseudo CSS, we would have un-semantic HTML tag clearfixe's as well. So in my believes they are both not winners. But there is no alternative for the time being when flexbox will become mandatory in upcoming years.
With inline blocks:
<div>
<div style="display:inline-block; width:30%;">col1
</div><div style="display:inline-block; width:70%;">col2</div>
</div>
Tags must be glued together/appended, to dismiss any gutter. The container div is necessary to force the items being part of a separate row.
With floats:
<div class="clearfix">
<div style="float:left; width:30%;">col1</div>
<div style="float:left; width:70%;">col2</div>
</div>
Clearfix is necessary to force a "row" (dismiss any normal flow items issues or floats after the floats)
Whether use one or the other is a matter of your goal (and taste). I must say I like inline-blocks more than floats, as long as you know the both of the col widths or use relative sizing (%). I thinks it's more intuitive and predictable than floats with clearfix, a fix" for issues that aren't even issues if it was used by how it should be used. Only the white-space awareness of inline blocks force you to use some funky html, that's a downside.
Ironically, tables do exactly all this (and even col-heights and vertically alignement's) without any issues. Since inline-blocks have to be placed in order, there's an motive for discussing here.
If we are talking about responsive, table 'loses' of inline-blocks. Let say you have 4 cols on a desktop and you want 2 cols on a tablet and 1 on a mobile. With inline blocks, you 'just' give the cols other width dimensions and they hopefully wrap nice (be aware of margins as they collapse). With tables, you're bound to actual rows, which can be quite stubborn. Flexbox is needed for a long time and looks beautiful. You can adjust the layout flexible on certain circumstances.
Bootstrap can be handy to learn how they did something. Just read in 3.0 they are using relative grid sizing. Which gives an issue with nested grids and aligning.
---- --a- ---- ----
---b------
.... ..c.
Col a is a normal parent col. Col c is a child nested col of b. It's hard to align c with a with relative sizing since the gutter is variable to the container, unless you're using padding and border-box model. But that way you lose a lot of flexibility. When you want the col to have some background and padding, you're messing up the grid system, so you have to use container which you style, which would clutter the code. I haven't studied if they found a solution to this. I haven't yet. I went to fixed pixels, but that means in responsive design you can only have a few fixed width's and for everything around mobile use a relative grid.
I prefer grid systems that use display: inline-block; rather than float, such as Pure (formerly Yahoo YUI Grid), because they internationalise without extra styles; change the text direction to right-to-left and the layout automatically reverses; floats don't do this. Floats also introduce the need to clear and other cross browser oddities. Any inaccuracies that inline-block may have over float can be remedied, as demonstrated by Pure. As to the criticism that display: inline-block; is not meant to be used for layout, perhaps the use of display: table; should also be banned for cross-browser centring. I would also question whether the term Semantic Web really applies to CSS since the term is primarily concerned with HTML and using its elements and attributes to impart machine readable meaning; the whole point of CSS is to style semantic HTML as radically as one wants to, hence classic sites like CSS Zen Garden.
I say that as long as the technique is not exploiting a bug, is not obstructing content to users and devices and is sufficiently supported then it is acceptable. There is no reason that one can't use CSS in unorthodox, but supported, ways, just like Stu Nicholls' CSSPlay.
Interestingly, Flexible Box is also incorporated into Pure grids, a superior layout system compatible with modern browsers (≥IE10 and equivalent browsers).
In the term of semantic web, the display: inline-block should be used when we want to place a block level element like <img> within line(s) of text. We shouldn't use inline placement for making the pages main layout. The element with display: inline-block also takes effect from properties like font-size and line-height of parent element. This will decrease the accuracy of page layout.
You would better get in the habit of using float instead of inline-block when making the page main layout.

use inline-block or table-cell for css grid

I'm looking into creating a set of css grid classes for webkit only browsers. Should be simillar to blueprit/bootstrap/compass, however I'd rather not use those because they rely on float positioning.
I'd like something like this:
span-1 {width:10%;display:inline-block}
span-2 {width:20%;display:inline-block}
and so on. Would there be any benefit to using display:table-cell vs inline-block for this? Or is there a better approach?
Actually display: table is really the solution you are probably looking for (because of your target browsers). It was added to browsers so people could get a grid layout without needing to use a table. You don't even need percentages (the number of columns you add will dictate the width of the children elements).
DEMO
The only real caveat comes in when you are doing mobile browsers and want a dynamic layout shift (media tag) to go from a horizontal list to a vertical list. I guess it is not too big of a deal to add you own media tags (and add a class to the wrapper)...
You probably could get display: inline-block working but make sure you use box-sizing: border-box because when you are working with percentages, even a single px off and things start wrapping..

Three Variable-Width, Equally-Spaced DIVs? What About Four?

I have some very simple sub-navigation that I'm trying to build across the top of the content area within my web site, but CSS doesn't seem to have any simple solutions for such a common problem: I want either 3 or 4 equally spaced DIVs across the top of the page.
1) e.g. 3 Variable-Width, Equally-Spaced DIVs
[[LEFT] [CENTER] [RIGHT]]
2) e.g. 4 Variable-Width, Equally-Spaced DIVs
[[LEFT] [LEFT CENTER] [RIGHT CENTER] [RIGHT]]
My solution for the first problem with only 3 DIVs was to float the left and right DIVs, and then assign an arbitrary size to the middle DIV and give it "margin: 0 auto". That's not really a solution, but assuming there are no changes to the navigation, it gives a rough approximation of what I want the results to be.
The solution I have for the second problem with 4 DIVs is to simply center a DIV in the same way as before, but then float two DIVs within that, e.g.
[[LEFT] [[LEFT CENTER] [RIGHT CENTER]] [RIGHT]]
But again, this requires applying an arbitrary size to the middle DIV for alignment, and if any language or image changes are made to the site, alignment values will have to be recalculated. As well, it's simply an over-complicated solution that requires merging structure with presentation.
Any help is greatly appreciated.
EDIT 07/20/2012 5:00PM
Alright, I put the "table-cell" solution into place using percents, but I encountered another issue within my slightly more complex implementation: the issue at hand is that each DIV I was referring to is actually a container for two more DIVs which are icon-label pairs, inlined either by float or by display:inline-block.
e.g. http://jsfiddle.net/c3yrm/1/
As you can see, the final element in the list is displayed improperly.
Any help is again greatly appreciated!
EDIT 07/20/2012 7:16PM
Final solution with arttronics' help: http://jsfiddle.net/CuQ7r/4/
Reference: jsFiddle Pure CSS Demo
The solution was to float the individual breadcrumbs while using a simple formula to determine the percentage of breadcrumb width based on the number total breadcrumbs.
You could use percentages, then it just comes down to simple math:
[[LEFT=22%]2% margin><2% margin[LEFT CENTER=22%]2% margin><2% margin[RIGHT CENTER=22%]2% margin><2% marginRIGHT=22%]]=100%/??px
You could then specify a width for its container and use
display:inline;
to keep them inline.
Note: If you use borders to see what the divs are doing that will add space unnaccounted for so you would need to reduce your elements width by 1% or so OR just change their background colors.
ol {
width: 400px;
/*width: 800px;*/
display: table;
table-layout: fixed; /* the magic dust that ensure equal width */
background: #ccc
}
ol > li {
display: table-cell;
border: 1px dashed red;
text-align: center
}
like here: http://jsfiddle.net/QzYAr/
One way I've found to do it is using flex boxes (or inline-flex).
Here is a great explanation and example of how it can be done.
I think in the future, flex boxes will be the superior way of handling this sort of thing, but until other browsers catch up with Mozilla's way of thinking for how to use the flex-basis attribute (with min-content, max-content, fit-content, etc. as values), these flex boxes will continue to be problematic for responsive designs. For example, occasionally the inner content (a_really_really_long_word) can't fit in the allotted space when the window is squished down, and so sometimes some things might not be visible off to the right of the screen if you're not careful.
I think perhaps if you make use of the flex-wrap property, you might be able to ensure everything fits. Here is another example of how this might be done (in Mozilla browsers anyway).
I tend to use flex boxes for letterheads or tables where the width is fairly fixed (not too small) because they usually space themselves nicely; I tend to use nested float and inline-block objects for websites where the content must squish down very small (as suggested in some of the other answers here).

Clean CSS fix of IE7's 'float: right' drop bug

I continuously find myself having problems with elements floated right in IE7.
I have read many Stack Overflow questions which are similar to this one but there doesn't seem to be any consistently clean CSS answers.
What I mean by this is is I want to see answers which DO NOT change the HTML. E.g:
Put the floated element first
Add a 'clear: both' div after the floated element.
I understand that sometimes the floated element doesn't account for its parents height and therefore sometimes fails to contain it properly. Occasionally I find myself 'adding layout' to an element with zoom: 1 which sometimes fixes it. Other times I find myself messing about in a conditional IE7 style-sheet which isn't the best fix in my opinion.
Note: What I mean by 'having layout' - http://www.satzansatz.de/cssd/onhavinglayout.html
I have also read other answers to do with using relative and absolute positioning (parent div and child div respectively). This pulls it up but often affects surrounding divs.
I would be happy to add a bounty to this question if someone can give an in depth explain as to the reasons this happens and a detailed discussion of the various fixes, IDEALLY CSS ONLY!
Many thanks!
EDIT
The most common problem I encounter is when I have something like this:
Left Sidebar - Main - Right Sidebar
Right will often drop when floated. Ideally this should be in the format Left - Right - Main, but I continuously find myself styling developers work (Drupal mainly) where this is the case and it is too much hassle to get them to change their work. Make sense? Because I'm styling developers work they never put the clear block in too (which personally I think is horrible and dirty anyways!)
Introduction
Your title indicates a desire to see a fix for the float: right drop bug, but your text implies some broader scope desire to see solutions to “problems with elements floated right in IE7.” There are many general problems with floated elements (right or left) in that browser. Even though one may question whether support of the IE7 browser is worthy of much attention any more, it undoubtedly will remain so for some people for some time. Therefore, I’m going to take the opportunity here to address numerous issues at once regarding floats in that browser. Note that many experiments and references below come from an excellent resource: http://www.brunildo.org/test/index.html.
CSS for the Containing Element
For a containing parent to the floated element the following css should be set:
.container {
overflow: auto; /* forces clearing of the child float */
zoom: 1; /* give it layout (this can be some other css that does likewise) */
}
Making sure it hasLayout is important to prevent types of margin and padding errors, a type of peek-a-boo bug, and allowing the overflow to clear. For a sequence of floats, some html may need changing if padding on the container is desired to work properly.
With regards to one “drop” issue with a float: right, you may want to avoid setting an explicit height or max-height on the container. A min-height is okay. Setting a height and then having the float be taller than the container makes IE7 not behave with following elements. There is no pure css solution that I have found noted.
If the container is itself position: absolute there can be issues with positioning a float that may require that float itself to be set to position: absolute instead of being floated.
References:
For overflow to clear -- http://www.quirksmode.org/css/clearing.html
Margins -- http://www.brunildo.org/test/IEFloatAndMargins.html
Peek-a-boo -- http://www.brunildo.org/test/iew_boo.html and http://www.brunildo.org/test/iew_boo3.html
Float sequence padding -- http://www.brunildo.org/test/IEmfloa.html
Avoiding height -- http://austinmatzko.com/2007/07/25/internet-explorer-7-float-bug/, http://www.brunildo.org/test/fenc7.html (and his similar problem link on that page).
Container is absolute -- Floating Too Far Right!
CSS for the Floated Child
For a the floated child element, the css (besides float: right) to set depends on two things:
Absolute Container
Again, as noted above, a containing parent that is absolute may require a change in how the child is handled.
Float is Also a Clearing Element
If the float is also going to have a clear set on it, then there are numerous issues that can arise depending totally upon the html and css of the elements around it. There is no single canonical fix, so look at the references below.
References:
Container is absolute -- Floating Too Far Right!
Also having clear -- http://www.brunildo.org/test/IEWfc.html, http://www.brunildo.org/test/IEWfc2.html, http://www.brunildo.org/test/IEWfc3.html
CSS for Child Elements of Container Before the Float
If the float: right follows an element in the html structure that should be to its left (and not above it), then that preceding element(s) must be float: left.
CSS for Child Elements of Container After the Float
A Clear Element
For an element after the float that has clear set, then if it has padding and background-color, make sure it also hasLayout to avoid a doubling of the padding; also this prevents extra space above the clear due to container padding, and avoids other margin issues.
References:
For padding -- http://www.brunildo.org/test/IEClearPadding.html and http://www.brunildo.org/test/IEFloatClearPadding.html
For margins -- http://www.brunildo.org/test/Op7_margins_float.html (look down the page for IE7)
A Paragraph Before a Clear Element
Having a paragraph with a margin-bottom and shorter in height than the float, located between the floated element and a clearing element, can create an extra gap between the clear and the float equal to that margin. There is no known pure css fix other than giving the paragraph a zero bottom margin (which may not be acceptable if the paragraph may go taller than the float).
Reference:
Paragraph following -- http://www.brunildo.org/test/IEFloatClearMargin.html
Conclusion
I cannot guarantee I have addressed every issue that may occur with a right floated object, but certainly many major ones are covered. As to “why” these things happen, it is all “bugginess` in IE7.
Have you tried to use the clearfix solution to collapsing divs? There are variations on this and there is a newer version but I don't have the url to hand, but this is standard clearfix css which you add to the parent element that is collapsing and causing issues with floated elements http://www.webtoolkit.info/css-clearfix.html. Chris Coyer has a better version here http://css-tricks.com/snippets/css/clear-fix/.
You say "I understand that sometimes the floated element doesn't account for its parents height and therefore sometimes fails to contain it properly" this is kind of true, the parent will collapse if all child elements are floated. This is due to the elements being removed from the normal flow, when this occurs the parent div is unable to calculate its height and collapses as if there isn't anything inside of the div.
But without seeing the page and the issue you are having I can only estimate that the issue is due to IE6-IE7's haslayout property which is really annoying, they sorted it out from version 8 upwards but it does add extra development time to your build.
But in most situations the clearfix solution is best as it doesn't add extra markup to the page such as
<div style="clear: both"></div>
this is old and out of date and should be avoided.
I hope this helps you, if you need any more information or I have not answered the question just ask.
We have been using the clearfix solution for years now.
.cf:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.cf { display: inline-block; }
html[xmlns] .cf { display: block; }
* html .cf { height: 1%; }
This is a simple CSS class which, ideally, has to be applied to a container that has any child float elements. Since you're restrictive about not changing the HTML at all, you can either:
replace all occurrences of .cf with your own div's selector [or]
use JS to apply the class (which is bad because users will see a broken layout a few seconds until the page loads completely) [or]
use PHP ob_start() + regex to apply the class [or]
just go vintage and rewrite everything using tables (as we used to do in the `90s)
It's simple:
Where you have float:right, add *clear:left.
Or where you have float:left, add *clear:right.
* for IE7-
Or for validation
*+html .class{clear:left/right}
I know it's been a year since this was posted, but I found a solution that I like for this. The gist is using 'expression' tag in your CSS for IE7 only to move the floated element to be the first element of the parent in the DOM. It will be semantically correct for all other browsers, but for IE7 we modify the DOM to move the floated element.
In my case, I have:
<div>
<h1></h1>...<p>any other content...</p>
<small class="pull-right"></small>
</div>
In my CSS for pull-right, I use:
.pull-right {
float:right;
*zoom: ~"expression( this.runtimeStyle.zoom='1',parentNode.insertBefore( this,parentNode.firstChild ))";
}
The result is that IE7 moves my <small> to be the first element of <div> but all other browsers leave the markup alone.
This might not work for everyone. Technically, it is modifying the markup but only in the DOM for IE7 and it's also a javascript solution.
Also, I understand there may be some performance issues with expression (it's slow), so perhaps it's not ideal there are a lot of floats like this. In my case, it worked well and allowed me to keep semantically correct HTML.

Resources