"Best clearfix ever?" - css

I saw this rather different method for clearfix here: http://www.marcwatts.com.au/blog/best-clearfix-ever/
It proposes adding the following CSS code which automates clearfix and does not require you to add a 'clearfix' or similar class to the elements you want to clear.
/* our Global CSS file */
article:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
aside:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
div:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
footer:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
form:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
header:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
nav:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
section:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
ul:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
/* our ie CSS file */
article { zoom:1; }
aside { zoom:1; }
div { zoom:1; }
footer { zoom:1; }
form { zoom:1; }
header { zoom:1; }
nav { zoom:1; }
section { zoom:1; }
ul { zoom:1; }
Are there any disadvantages to this method? Could this end up clearfix'ing elements that you may not necessarily want clearfix'ed? Or are the rules such that this will account for any situation?

I think that's a bad idea. Are you really going to trust somebody who seemingly forgot to do this:
article, aside, div, footer, form, header, nav, section, ul { zoom:1; }
Clearing floats is not a complicated thing to get right.
It should be handled on a case-by-case basis, not sledge-hammered onto "every" element.
Doing that will come back to bite you in some way, I'm sure of it.
For one thing, I agree with #Guffa's answer.
An edge case reason against it concerns IE7: http://www.satzansatz.de/cssd/onhavinglayout.html
zoom: 1 is a common method to provide something known as hasLayout to elements. Applying hasLayout to an element fixes certain kinds of rendering problems, but it can also cause other problems. A quote from the linked document:
Don't give layout to all. Poison in that concentration,
having layout is not the cure, it
changes the rendering fundamentally.
I personally like to use the overflow: hidden method to contain floats. When that doesn't work, then I use clearfix.
You should use the version of clearfix from http://html5boilerplate.com/:
.clearfix:before,
.clearfix:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.clearfix:after {
clear: both;
}
/*
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.clearfix {
*zoom: 1;
}

Could this end up clearfix'ing
elements that you may not necessarily
want clearfix'ed?
Yes. I would not like every div element to be cleared.

Are there any disadvantages to this method?
One would be that it won't be enough in < IE8, since the 'after' element isn't that well supported. More about that at CSS tricks

In Cascade Framework, I'm using the following clearfix on all "block level" elements :
div:after {
content: "";
display: table;
}
div:after {
clear: both;
}
div {
*zoom: 1;
}
I never encountered any problems with this technique, except for minor quirks when using third party JS libraries... which can easily be fixed by "unclearfixing" the parent element.
Personally, I think clearfixed block level elements are lot more intuitive to work with and I don't really want to go back to working with floats the traditional way anymore. The only reason I see not to clearfix all block level elements by default, is because it's non-standard behavior and it might confuse the hell out of other people reading your code.
In cases where you actually want a parent of a floated element to collapse, an alternative strategy would be to use display: relative for the parent and display: absolute for the child. I haven't encountered any use case so far where this strategy isn't a suitable alternative for collapsed parents of floated elements.

I've been clearing all divs globally for the past couple of years in my projects, and it has been working great for me. In approximately 95% of the cases where I use divs, clearfix has worked like a charm when applied to a site globally. There are certainly cases where a potential issue will arise, and I end up undoing the clearfix for any problematic divs. The CSS declarations I use are:
div:after {
clear: both;
margin: 0;
padding: 0;
display: table;
font-size: 0;
line-height: 0;
content: ' ';
visibility: hidden;
overflow: hidden;
}
div {
*zoom: 1;
}

Related

How to hide everything except textarea while printing using special css

I am new to HTML, CSS and Javascript. I am learning things. WHile learning, I came to a problem how to print only a textarea from HTMl while printing using CSS only.
#media print {
* { /* the asterix denotes every element */
/* belt and braces */
display:none;
visibility:hidden;
height:0;
overflow:hidden;
}
textarea {
display:block;
visibility:visible;
height:inherit;
overflow:visible;
}
}

Chrome does not re-calculate width when height changes

I have a list of thumbnails with links and images, so when the user hover an li element, it's height becomes 100%, but the problem it works wrong in Chrome for some odd reason. I don't understand why in Chrome the hovered li width doesn't adjust to its "new" size.
(Note: this is a simplified version of my problem)
Also, this problem occurs only on :hover. but not, lets say, with :nth-child
Playground link
Update: problem continues... See my solution in the answers, BUT the problem continues..I've zoom in with the mouse and you will see it happening..note that number of images can be huge.
Update 2:
Force a redraw every mousehweel event fires...
thumbs.hide().show(0);
My solution: Solution playground
The idea is to trick Chrome to re-calculate the width, by giving the image a new height that is almost the same on the li:hover state. BUT this isn't enough for Chrome. transitions must also be applied on the img. This is all voodoo coding, but this is the least-ugly solution I could come up with:
ul{ list-style:none; display:inline-block; height:80px; white-space:pre; width:100%; }
li{ display:inline-block; vertical-align:middle; height:60%; -webkit-transition:.2s; transition:.2s; }
li:hover{ height:100%; }
li a{ height:100%; padding:0 2px; display:block; }
li a img{ height:96%; -webkit-transition:.2s; transition:.2s; }
li:hover a img{ min-height:96%; }
I am new here and I am not sure if this is a good practice but I will post my observation and not a precise solution:
The same problem appears on Opera.
This seemed strange to me - when li:hover a img{ border:1px solid black; } or any similar css code that is not supposed to make any change to the current situation is added it all starts to behave very strange. ex - http://jsbin.com/operib/43/edit
And here it is the solution I do not find elegant, just a quick fix:
http://jsbin.com/operib/39/edit
EDIT: After testing #Carol McKay's result I realized that the transition is making the whole mess. The next link (node 58) is node 43 linked above (which is basically node 1 just added border to the image on hover) with removed transition and it works just fine http://jsbin.com/operib/58/edit.
It seems that any css rule should be added on hover so the <img/> dimensions are recalculated.
Apply transition to the image instead.
css
ul{ list-style:none; display:inline-block; height:80px; white-space:pre; width:100%;
}
li{ display:inline-block; vertical-align:middle; height:60%; }
li a{ height:100%; padding:0 2px; display:block; }
li a img{ display:inline-block; vertical-align:middle; height:96%; transition:0.15s; - webkit-transition:0.15s; }
li:hover{ height:100%; }
li:hover a img{ height:100%; opacity:1; }
http://jsbin.com/operib/83/edit

nth-child and before

I'm having an CSS problem, i need to achieve this
article div#comments-wrapper ul.sub-comment:before {
width:1px;
height:67px;
background-color:#e4e4e4;
position:absolute;
margin-left:-595px;
margin-top:-36px;
content:'';
}
article div#comments-wrapper ul.sub-comment:nth-child(1):before {
height:37px;
margin-top:-6px;
}
but i can't put two pseudo elements like that, and i've tested it (doesn't work),
also tried some other ways but didn't manage to figure it out.
:nth-child() doesn't filter by classes or anything. In your code, your first ul.sub-comment isn't the very first child in #comments-wrapper, so it doesn't work.
Instead, use this selector technique and invert your height and margin-top styles as follows:
article div#comments-wrapper ul.sub-comment:before {
width:1px;
height:37px; /* was 67px in your code */
background-color:#e4e4e4;
position:absolute;
margin-left:-595px;
margin-top:-6px; /* was -36px in your code */
content:'';
}
article div#comments-wrapper ul.sub-comment ~ ul.sub-comment:before {
height:67px; /* was 37px in your code */
margin-top:-36px; /* was -6px in your code */
}
Basically, instead of :nth-child(1) (or :first-child for that matter), use a sibling selector with another ul.sub-comment to apply the original styles to all subsequent ul.sub-comment elements after the first one.
Updated fiddle (also inverted the background-color styles so the first one remains blue)

IE6 css hacks and their standard css equivalence?

in the following there are some IE6 css hacks I need their standard equivalence.
.header {
zoom: expression(runtimeStyle.zoom=1);
z-index: 1;
}
.hmenu ul li {
float: left !important;
}
ul.hmenu li {
margin-left: expression(this.previousSibling==null?'0':'1px');
}
.nav {
position: expression(runtimeStyle.position='relative');
}
ul.hmenu li {
margin-left:expression(this.previousSibling==null?'0':'1px');
}
This is equivalent to li { margin-left: 1px; } and li:first-child { margin-left: 0; }.
I don't see the point of the other expressions, other than to set the properties in an IE<9-only way.
zoom: expression(runtimeStyle.zoom=1);
is setting zoom:1 so you can achieve hasLayout
float: left !important;
!important is supported in all browser and simply adds another layer of specificity to your declaration. i am quite positive that !important is not important in the above css...no pun intended :)
position: expression(runtimeStyle.position='relative');
runtimeStyle object represents the style of the object, which overrides the format and style specified in global style sheets, inline styles, as well as HTML attributes.
in this case, on pageload, .nav's position is set to relative

How can i remove all attributes from any css selector? To override and reset any css id selectors?

#search-box {
-moz-border-radius-bottomleft:0px;
-moz-border-radius-bottomright:0px;
background-color:#ffffff;
border:0px solid #CCCCCC;
float:right;
padding:8px;
position:relative;
top:0;
width:20em;
}
#search-box {
/*remove all css declaration here*/
}
You can't. You would have to manually reset each of them. If you need to jump between major differences, when a user clicks the element, for instance, you can remove these from the element itself, and put them in a class. So this:
#search-box {
color:blue;
}
Becomes this:
#search-box {
color:red;
}
#search-box.focused {
color:blue;
}
Now any time you need to make radical changes to the display of an element, add or remove the .focused class.
You can't remove all attributes. You should be more specific in your first rule so that it only targets those elements that you desire. Either that or you need to explicitly set the values that you want on the second rule.
The question makes much more sense, if you use classes;
HTML:
<div id="site-search-box" class="search-box">
Then reset the attributes, e.g:
CSS:
#site-search-box {
position: static;
padding: 0;
width: auto;
}

Resources