Let’s say you want to make a layout like this:
That’s reasonable right? Especially if your article was about cats liking to be the CENTER of attention. GET IT?! (Kitten via PlaceKitten).
Well this isn’t particularly easy to do. Our current layout methods aren’t really built with this in mind. In fact sometimes they feel like they don’t really have “web design” in mind. AM I RIGHT? Even the bleeding edge CSS layout systems I don’t think would handle this very well. This is a little bit like float
, as the text wraps around the image, but the text wraps around both directions, so it would be a bit like float: center;
or float: both;
which don’t exist.
But this is doable! Proof:
We’re going to do it by using floated pseudo element placeholders. We’ll put one in each column of text1, one floated left, one floated right. The pseudo element should be the height of the image, and half of the width (or so… remember you’ll want some padding and there is the gutter to factor in).
Essentially:
#l:before, #r:before {
content: "";
width: 125px;
height: 250px;
}
#l:before {
float: right;
}
#r:before {
float: left;
}
Now there is a hole in the text ready to place our image there. We could do that by absolute positioning it there, as in the demo. Or you could just leave it in an element above, centered, and use negative top margin on the columns to pull the text up around.
1 Note we’re using div’s for the columns of text, not CSS columns, which would be cooler and more semantic, but it’s not going to happen.
Ooh. Great tip and something different. Makes so much more sense and I have been using more column style layouts given the increase in people buying newer computers with larger screens or others wanting magazine layouts and something a little different than the common single block text.
Thanks for this great tip! Looks awesome and actually much more natural too!
This is great! You would think there would be something in the spec for doing this more intuitively though. It reminds me in some ways of the sandbag div technique for wrapping text around images.
My favorite “float: center;” technique is to set an element to “display: inline-block;” and set it’s parent to “text-align: center;”. It doesn’t have exactly the same behavior as this example, but it is a very useful technique from time to time.
very interresting
thanks
Chris is getting back into real css tricks! Thanks, always a pleasure to learn new techniques.
very clever .. available for the ads, thank you
OMG it doesn’t work in ie 5.5!!!!!!!!!!!!! ASFASDASFASFADSDSF!
( Nice tip ;) )
Hey what’s cool though is it should work in IE 7 and up, which is pretty decent as far as neat tricks go.
Seriously, what client asked you to support IE5.5? Still got Windows 95/98 clientele?
^Sarcasm.
Definitely a solid tip. It’s ridiculous that you have to go to this length in order to achieve something this simple, though. I guess we’ll have to wait until CSS4….
you are using IE5.5 ?……
I think it’s hard to get across sarcasm in text ;-) Great tip however Chris, I’ll give it a try. Thanks
It’s stuff like these I like the most, fun workarounds that make sense and have a solid base. Nice :)
Hehe, I would never get to it myself.
With some patience you can get even more interesting float:
http://rmcreative.ru/blog/post/slozhnoe-obtekanie-tekstom
That’s very cool, the ol’ shim technique. Sort of the “point” of this is that pseudo elements mean that the code stays nearly perfectly semantic, no extra elements needed.
I don’t know how many times I have seen someone try to use float:center – you’d think after watching it not work several times they would stop. So, this title caught my attention :)
Thanks for the tip! The pseudo selectors are pretty awesome and I like seeing different ideas come out on how to use them.
Hey Chris,
I would not include the image in the markup as it breaks IE6/7. Instead, I’d use it to style both pseudo-elements with a background-image. That way you get the same effect with a nice “fallback” (as the image would not overlap the content).
Hi Chris, awesome tip. Jaw dropping one :)
Your site is rightly named CSS-Tricks, presenting awesome and rarest tricks in whole WWW.
Hey Chris,
I had to achieve the “float: center” look a while back and it had to work on IE6, so I used spacer images instead of pseudo element – which, to be honest I hadn’t thought of.
Will update my approach if I ever get another request for it!
Cheers,
Hey thanks, Chris. I am so excited about this!!! Maybe it’s my print background that has always made me itch for this capability, but I’ve tried to achieve the “center float” many ways and always failed.
cheers-
Love it! Gives new meaning to the term ‘magazine layout’. ;-)
This looks like a great idea. I have a question on implementation:
When you have multiple elements to center, would you need to use something like this in your stylesheet with a unique callout for EACH element?
#element1 #left:before, #element1 #right:before { content: “”; width: 225px; height: 250px; }
#element2 #left:before, #element2 #right:before { content: “”; width: 225px; height: 250px; }
Thanks for your advice.
~Jeff
Actually it makes more sense if the sizing requirements are different:
#element1 #left:before, #element1 #right:before { content: “”; width: 225px; height: 250px; }
#element2 #left:before, #element2 #right:before { content: “”; width: 100px; height: 150px; }
Sorry, I couldn’t edit my prior comments… so here’s another update to accommodate ‘center floating’ multiple elements:
For multiple elements you can’t us duplicate ID’s, but have to use classes, so this should work:
#element1 .left:before, #element1 .right:before { content: “”; width: 225px; height: 250px; }
#element2 .left:before, #element2 .right:before { content: “”; width: 100px; height: 150px; }
very neat !!, is it IE proof ?
It isn’t completely IE proof. I just tested it.
IE8 and IE9 are doing it good.
IE7 and lower fail…
@Chris Coyier
thanks for the blogpost. Might need this sometime.
Thanks for sharing that, I’m still in the process of learning all these cool css-tricks and your website is fantastic!
I look forward to more posts by you :)
That is a really cool trick. Very simple. As soon as I read “We’re going to do it by using floated pseudo element placeholders.” I knew what you were doing, but without that ‘trigger’ I would never thought of such a method. In fact, I had never even considered such ‘problem’.
Very nice work!
Love the effect and have tried (unsuccessfully) to re-create the look for IE7 and down. I had thought the inclusion of Dean Edward’s IE7.js would solve the problem but this seems to be having issues currently with the :before and :after selectors so no luck.
I’ll batter on with my efforts and update here if I have any luck.
It seems that a jQuery solution is the best answer – either through the API (http://api.jquery.com/before/ and http://api.jquery.com/after/) or this plugin http://jquery.lukelutman.com/plugins/pseudo/.
Maybe a better way is to simply include IE7 and below specific style sheets that correct the layout for the browsers that cannot support these selectors.
You can replace the pseudo elements with spacer images, or blank tags since IE7- doesn’t support the :before, :after pseudo elements. Here’s an example using spacer images.
Cheers,
Thanks Fabien but that solution fdoesn’t work great for when you need to integrate with a CMS and have to rely upon the client inserting numerous extra elementa. I’m still looking for the perfect CSS based solution for older browsers I guess!
I wish we could do this with column-count CSS property.
Very cool, Chris. I can see a number of opportunities where I’d like to implement this.
I followed your explanation and code and managed to come up with an OK first try; as soon as I figure out how to include an image here, I’ll share a screenshot of it.
Thanks for sharing the great concept and clear explanation.
I just stumbled across exactly this Problem – 1 week ago ;)
I thought how to build this in an cms template.
Thanks a lot. Will test it, but im sure it will work ;)
Hey!
We had this problem just the other week. I colleague of mine wanted to do something exactly like this and I told him, that it just won’t be possible.
But now, when I see the solution for the problem, it seems to be so much easier to solve than I expected!
Thank you so much for that! :)
I followed your explanation and code and managed to come up with an OK first try; as soon as I figure out how to include an image here, I’ll share a screenshot of it.
Very good thinks ~~~~
Great tip, but I was hoping it used css3 columns. Oh well.
Great tip! ‘float: center;’ has been a long time dream of mine. This works quite well. Thanks!
This one seems pretty good.
One thing though, why don’t they create a float:center css itself?
It’s very cool and useful!
So does the :before create some kind of virtual div of the specified width and height?
Cause from what i understood from the schematic display, the created :before areas act like elements with “display:block;”… Do browsers treat them as such?
It’s not a DIV, but yes, it’s a generic block level element. (and it’s only block level because floating it makes it block automatically, otherwise it would be inline.)
Does it support IE6,IE7?
Nice Idea that i may need in future thanks.
That’s pretty clever thanks for this I will try it out :)
Oooo very convenient…for now!
You should definitely check out box-pack:center, it’s another way of achieving this: https://developer.mozilla.org/en/CSS/-moz-box-pack
IE6-7 don’t have :before support, that’s why we need to optimize this example for Microsoft :)
using some special technics with js expressions for example
No need to, just show them a simple version with the image at the top left and move on.
I love it! I’m not a hard core coder but am I right that this is a css3 (only) trick?
Really nice tips for creating the effect…
Doh! o_O
Thanks for the tip.
Great technique, Chris! I’ve written up a variation on my blog: it uses
display: table-cell
to create the columns, simplifying the CSS and markup somewhat. Thanks for the trick!am i correct in thinking that if you wanted to accomplish the reverse of this (ie 2 images with text in the middle) I could do this with the following?
The pics referred to in this example are stupid.
perhaps i am making this harder on myself than it should be
This is just one of many of the kinds of CSS tricks that makes the whole HTML layout issues just a little bit more complicated than it ought to be.
You are not responsible for the dilemma, but are not helping us to resolve issues.
This trick is like stuffing your socks into a broken window.