I'm making more of an effort to separate my html structure from presentation, but sometimes when I look at the complexity of the hacks or workarounds to make things work cross-browser, I'm amazed at huge collective waste of productive hours that are put into this.
As I understand it, floats were never created for creating layouts, but because many layouts need a footer, that's how they're often being used. To clear the floats, you can add an empty div that clears both sides (div class="clear"). That is simple and works cross browser, but it adds "non-semantic" html rather than solving the presentation problem within the CSS.
I realize this, but after looking at all of the solutions with their benefits and drawbacks, it seems to make more sense to go with the empty div (predictable behavior across browsers), rather than create separate stylesheets, including various css hacks and workarounds, etc. which would also need to change as CSS evolves.
Is it o.k. to do this as long as you do understand what you're doing and why you're doing it? Or is it better to find the CSS workarounds, hacks and separate structure from presentation at all costs, even when the CSS presentation tools provided are not evolved to the point where they can handle such basic layout issues?
Clearfix is unnecessary most of the time, and the popular version of hack is needlessly verbose and complicated.
You can get clearing effect by applying overflow:hidden to the container. If container doesn't have fixed height, it will stretch to size of content anyway. It's not a hack, but specified behavior that works in all browsers.
And when you really need overflow:visible you can still clear without extra element in the markup:
.container::after {
content:""; /* not "."! */
display:block;
clear:both;
}
and that's perfectly standard CSS 2.1. In IE versions that don't support CSS 2.1, hasLayout happens to have desired effect:
.container {
zoom:1;
}
Yours is the right approach. Rules are created for those who do not understand them. If you know all pros and contras, make your own call.
You are particularly justified in this case. CSS decided to ignore common wish to separate content A from content B horizontally, so you have to choose a hack you dislike least. I compare the three solutions already presented here.
Your solution is bad because it changed content of the document, inserting element C whose only purpose is visual separation between A and B. Content should not serve layout purpose.
Karpie’s solution is slightly worse (in my book) because it does the same in a sly way. Pseudo element ":after" was not designed for that. It has a great advantage, however, of never actually changing the HTML.
PorneL’s solution achieves desired separation between A and B by radical change of properties of A. The change will not only separate A from B, but also separate A from preceding content, change the way width of A is calculated and so on. Of course, sometimes it’s perfectly OK, but you have to be aware of those unexpected side effects.
The choice is ours.
I definitely don't agree with the idea of using extra markup just to clear divs.
I favour the 'group' approach - putting class="group" on the parent div, with the following CSS:
/* Clear groups of floats by putting class="group" on their parent */
.group:after
{
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
And in an IE-specific stylesheet for IE6/7:
/* IE7 */
.group
{
min-height: 1px;
}
/* IE6 */
* html .group
{
height: 1%;
}
This was detailed in CSS Mastery, by Andy Budd. It stretches semantics a little bit, but it makes sense - you're grouping together floated divs, which obviously have some relation to each other.
edit: I wouldn't consider this a huge hack or workaround either - the method has been around for years in various incarnations, (usually known as the 'clearfix' method), and I don't see it going away anytime soon.
Related
So while working on a project I noticed that when I scrolled to the bottom the scrollbar would bounce back up a page.
Originally I had to make the front page have less vertical space for the footer and add the space for every other page.
So I moved:
body {margin-bottom: 150px;}
To:
body:not(.home) {margin-bottom: 150px;}
I'm answering my own question here though it's very clear Chrome has widespread issues with the scrollbar behavior in general. For people who aren't web designers it is possible to override the behavior on a live website and in some cases (with extreme subjectivity) programs (e.g. maybe the bookmarks page) though the issue in browser pages is overriding the browser's internal CSS which isn't always possible.
The fix, at least in the scenario I faced, was to split the margin in two and give the other half of the spacing to the padding-bottom.
So in example, this:
body {margin-bottom: 100px;}
Would become this:
body
{
margin-bottom: 50px;
padding-bottom: 50px;
}
This is however generally not an acceptable solution as there are very explicit reasons why margin and padding are two different contexts however the project I'm working on is very graphically heavy and requires breaking proper CSS conventions.
For non-web developers/designers who may come across this issue and page, as I mentioned in the question above, it is possible to override a website's CSS code if the CSS selector can be specific enough to only effect one website. The code would then have to be applied to the browser's master style sheet. I've done this in the past to negate Google forcing ads even around my Adblock Plus filter subscription and won. Each browser has it's own way of applying default styling, since this is a Chrome specific issue and I'm not as familiar with Chrome I did some digging to provide some bread crumbs and hopefully make someone's life just a bit easier:
https://superuser.com/questions/52967/change-default-css-of-google-chrome
I'm about to update http://getcrow.eu and have one "issue" to solve that would make the framework everything I always wanted it to be.
Important to know:
Crow does not use tables, absolute positioning, floats or clearfix'es and it should stay that way.
We know that putting inline-blocks next to each other like so:
<div class="parent">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</div>
with CSS:
.parent {
> div {
display: inline-block;
}
}
Creates white-spaces between the blocks. We also know there's a handful of solutions to prevent the white-spaces from creating space, which is highly required if creating a grid framework with this method.
Beneath I list the methods that I'm aware of and why I don't want to/can't use them:
(SKIP IF YOU WANT TO GET TO THE QUESTION)
Comments in the HTML inbetween children div's.
No-go because: it creates ugly HTML that the developer, using crow, must be aware of and work with.
Breaking lines at the end of children tags/ not using closing tags.
No-go because: same as above
Using minus (-) margins on .parent-wrapper.
No-go because: specified margins depends on document font size which mean the grid could break in responsive markup where html { font-size:{X}px; } changes.
Setting 0px font-size to .parent and "reset" the font size on children (this is the method I'm currently using).
No-go because: I don't want the developer using crow to force-set the children. I just want the inheritance to be natural without a grid that's setting the font size downwards for me.
Using Javascript to remove all white-spaces from .crow elements.
No-go because: I want the framework to be pure CSS and no js. This could also "flick" the DOM after pageload if user has bad connection.
Loading a font with font-family on .parent that has no white spaces.
No-go because: loading in an extra font just to get the grid framework is just wrong. Especially as you have to download extra files (font-files) and declare fallbacks for all browsers.
Using letter-spacing -{X}px on .parent.
No-go because: same as .3 (see above)
Using flex box.
No-go because: the framework focuses on vertical centering (if desired) and flex box lives it own life when it comes to that. I'm also making sure the grid is supporting IE8 which it does today.
So basically I'm searching for a - unknown/not yet discovered/way that I'm not aware of - for removing white spaces in between inline-blocks. I want it to be pure CSS. If you have a method that you know of/think would work - I can try it on different browsers.
Resolving this would surely make Crow the best grid framework. I'm already using it for various websites and I can tell that the possibilites are many when given the ability to easily position elements center vertically.
Sidenote:
Marking up the DOM like so: <div class="parent"><div>Block 1</div><div>Block 2</div></div> does the job just like I want it to. But that would require the developer using Crow to mark it up that way. And I don't want to rely on a framework creating that HTML.
InuitCSS (my choice of framework lately) uses a similar system. As wonderful as the use of display: inline-block; is in a grid system, it does appear that the whitespace issue, is an inherent one; with little chance of resolution beyond the current workarounds.
I agree that the use of comments or closing tags does introduce some issues with CMS entries, and a certain amount of mental overhead for the developers involved; but not an unmanageable amount.
If you want to have a look at Inuit's grids I would recommend it's GitHub found here:
https://github.com/inuitcss
I would also advise reading this issue, in-which Inuit's creator; Harry Roberts, weighs in on the various solutions this problem. Whilst it may not tell you anything you don't already know, it is an interesting (if outdated) discussion on the matter.
https://github.com/csswizardry/inuit.css/issues/170
I know that the above may not solve your issue, or even shed any light on the matter, but I hope it can be of use.
Using a float is your best option.
.parent div {
float: left;
}
Following your comments below you could use a negative margin.
.parent div {
margin-left: -4px;
}
But this may change browser to browser.
I'm experimenting with ways to create a two-tiered multi-column form that looks balanced. My latest attempt involves enveloping each label/input in an li and having them float into place. The attempt is somewhat successful, but there is a dimension issue that I can't resolve.
The form is 600px wide and I made the lis 280px which would put the two columns roughly centered in the form. However, the effect is lopsided; everything is way too much to the left. It's like there is a huge margin of about 150px on the right hand side of the form - only there isn't.
In analyzing it, I noticed that the inputs are actually measuring at 175px. However, if I try to increase the width, it goes to a new line, so they are acting like they are 280px. But you will notice in the jsfiddle, the last li is extending to the full width - 600px. Therefore, it can't be a result of any fieldset formatting. Furthermore, if I change the float to 'right', the 150px fake-margin is still there. Firebug detects all margins and padding as normal.
I just don't get it.
I've tried renaming, applying additional classes, changing order of the li, removing attributes and adding other ones, and changing styling protocols... but usually I just make things worse. I would give up on the ol li concept altogether if any of my other techniques came as close to providing the display I am looking for.
What's causing that 150px right margin? And how do I get rid of it?
I need to understand this as the second part of the form is supposed to have two and three columns. So if lis cannot provide consistent widths, I have to try something else.
Here is the link: jsfiddle
[http://jsfiddle.net/9344a/]
Thank you in advance. (I've tried to clean it up, but the CSS/HTML may be a little bit messy as a result of trying different combinations. Let me know if anything is still difficult to understand.)
You can give
fieldset.partOne
{
text-align: center;
}
The problem was actually a compounding of errors.
First, the input size was incorrectly targeted through li when it should have been targeted directly.
Example: fieldset.partOne ol li { width:280px; padding:5px 0 } WRONG! fieldset.partOne ol li input { width:280px; padding:5px 0 } or simply fieldset.partOne input { width:280px; padding:5px 0 }
In addition, setting the width of the ol li to 100% (a misguided attempt to increase the size of the input) would obviously prevent the float.
The margin issue is caused by fieldset.partOne ol li { width:280px; padding:5px 0 }. Removing this width eliminates the fake margin. Not quite certain why, but the lesson is ol li works slightly differently within forms, so be aware of that.
My concept for this form was fairly odd, and I made several errors with both my HTML and CSS in trying to achieve the end result. So I went back to the beginning and rebuilt from scratch and was able to create a non-standard multi-column form that met my odd criteria, used only CSS, and worked across most browsers.
The Stackoverflow posts were invaluable in addressing all the little quirks that I came across, so I thought I'd return the favour and provide a jsfiddle that may help other newbies identify what they want and possibly how to get there.
I would have found something like this enormously helpful.
Issues addressed:
Aligning two and three column forms with various sized input elements.
{ol li} or {div}? {li} Not a good solution for non-standard formats. I had to use {li} for one section and {div} for another section to make the form work.
{select} sizing inconsistent. It usually has to be larger than your {input}
Keeping smaller {inputs} from floating into gaps.
Aligning odd shaped {input} and {label} fields.
Font sizes and styles reverting to browser default (reset not applying to HTML5?)
A non-resolved issue is FF top-aligning {select} data. There are many posts regarding this issue, but I have not found a good solution as of yet (one that targets only FF and does not affect other browsers). This is not a priority for me, but if it is for you, lots of advice is available. Do a search.
Here is link that displays the form and shows the code: http://jsfiddle.net/LAVJn/1/
Remember that this is written by a newbie, and you will certainly find many ways to improve upon it. But it does work and may be a good place to start or at least refine any questions you may have.
I don't think I am breaking any protocols doing this, but please let me know if that is not the case.
My goal is to get such effects with borders in pure css. I want to ask You is it possible (or I have to use images)? Do I have to use so kind of span attribute or a outline or something else? Maybe You know were I can find tutorial how to do it?
Another possibility that doesn't use borders, but is pure CSS is some wacky work with pseudo elements.
For example:
p:after {
content: '';
background-color: red;
position: absolute;
width: 20px;
left: 0;
top: -2px;
bottom: -2px;
z-index: -1;
}
You can see the demo here: http://jsbin.com/iduvoj/1/edit
Here is another demo of your last example: http://jsbin.com/igotul/1/edit
Now this depends on a few things, like how many elements you'll be stacking, whether or not your paragraph can have a solid background color, etc. But there's a chance it'll work.
It also only depends on :before and :after which are fairly well supported: http://caniuse.com/#search=before
This will be tricky.
The best I can offer you using borders is CSS border-image, which will indeed allow you to design pretty much arbitrary border designs. You can read more about it on MDN.
It has the advantage that it's designed to handle stretching images across the length of the border and having separate images for each side and corners, etc, as necessary so it's very flexible.
I won't give an example beyond those on the MDN page linked above, because the CSS code itself is relatively simple; the main thing you'll need to get it working will be the actual images, and that's something you'll need to provide yourself.
However the main problem you'll have with border-image is browser support. It's a relatively recent addition to CSS, and some fairly modern browsers don't support it. That includes IE10. Depending on what you need, that may scupper this as a solution.
So the alternative solution that will work better cross-browser is simply to have the borders defined as background images. This is fairly obvious, and actually works quite well. If the boxes can vary in height a lot then you may get issues with scaling, but this can be avoided by using multiple background images.
Hope that helps.
I've made the jump from HTML table layout for designing webpages to CSS about a week ago and have since been reading more about it. Yesterday, I read a long post here on Stack overflow where users were knocking float and how deprecated they are for layout. There was a lot of talk about inline-block being used in its place.
I have an HTML5 design that I just finished and it looks fantastic in Firefox and Chrome, but when tested in Internet Explorer 7, 8, and 9, the design absolutely explodes. It seems to me that anything in this design that I've floated right is not honored in IE. It just seems to wrap under whatever is to the left of it.
I'd like to know if I'm OK with floats or if I should I be using inline-block instead. An example of how to have two divs next to one another where one is on the left side and the other on the right, using inline-block would be nice.
Floats were never meant for layout.
They’re simply meant to take an element, put it to one side, and let other content flow around it. That’s all.
Eric A. Meyer, in Floats Don’t Suck If You Use Them Right
The early web was influenced by print/academic publications where floats are used to control the flow of text around figures and tables.
So why did we use them for layout?
Because you can clear a footer below two floated columns, float layout
came into being. If there had ever been a way to “clear” elements
below positioned elements, we’d never have bothered to use floats for
layout.
Today, the CSS Flexible Box Layout Module flex and the CSS Grid Layout Module grid are optimized for user interface design and complex layouts and are expected to complement each other.
Grid enforces 2-dimensional alignment, uses a top-down approach to layout, allows explicit overlapping of items, and has more powerful spanning capabilities. Flexbox focuses on space distribution within an axis, uses a simpler bottom-up approach to layout, can use a content-size–based line-wrapping system to control its secondary axis, and relies on the underlying markup hierarchy to build more complex layouts.
Flexbox and Grid are—as of this writing—W3C candidate recommendation and candidate recommendation draft, respectively. Flexbox is supported by all major browsers and has known issues in IE11. Grid is supported by all major browsers but IE11 supports an older version of the spec.
This question is from 2012 and the other answers are outdated.
Floats should not be used for layout anymore (though you can still use them for the original purpose - floating text around images).
Flexbox is now widely supported and is better for layout.
Floats should work fine, although it depends on how you've used it - how about a link to your design?
inline-block doesn't work correctly in Internet Explorer versions less than 8: http://www.quirksmode.org/css/display.html
You can use this example in inline
<div id="firstdiv">
That is the first div
</div>
<div id="seconddiv">
That is the second div
</div>
style.css
#firstdiv{
display:inline;
background-color: #f00;
}
#seconddiv{
display:inline;
background-color: #00f;
}
it will be work at IE8 and higher but if you wanna use it in IE6 and 7 make the following code in style.css
#firstdiv{
display:block;
background-color: #f00;
float: left;
}
#seconddiv{
display:block;
background-color: #00f;
float: right;
}
if you use HTML5 and CSS3 and you want it work with IE6 read the following article 5 Tools to Make IE Play Nice With CSS3 and HTML5 in WordPress
you can read that article too it is very useful difference between block, inline and inline-block