Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fallback for old (and annoying) browsers for a creative use of "Flex-Box"

I'm not a big fan of questions that provide some criteria without reasoning for a solution to be acceptable but in this case, I have one too: No JavaScript for compatibility, except Modernizr. (The reason is that they slow the page down too much.)

I used the new and fancy CSS3 flex-box to create a menu, which displays some extra links, if there is some extra space. You can see a (hopefully) working demo here.

The big question is: How can I provide a fallback for the (cough)annoying(/cough) Internet Explorer and the old browsers without using the somewhat famous FlexieJS library? Is this achievable with just css2, other than setting a maximum percentage width for the menu (ul)s (which does not really work)? Could you at least point me in the right direction? Thanks!


UPDATE

I gave another try but still couldn't figure it out on my own. Any help is really appreciated! Thanks a lot =) You can find my attempt here.


like image 340
Ege Özcan Avatar asked May 10 '11 15:05

Ege Özcan


3 Answers

Being a huge fan of cross-browser compatibility, I'm not a huge fan of CSS3. I think that if you can achieve something using pure CSS, why use Javascript? If you're looking for simple a fallback for CSS2, use overflow: hidden. I'll do my best to explain how this simple attribute can essentially achieve the same effect.

<div>
  <ul>
   <li>Elem 1</li>
   <li>Elem 2</li>
   .
   .
   .
   <li>Elem n</li>
  </ul>
</div>
  1. Set the width of the div element to whatever the maximum width you would like your list to be, and height to the height of your elements.
  2. Set your ul to display: inline; so its width can expand depending on the size of the inner elements.
  3. Set your li elements to float: left; (or right) so that they appear horizontally. The height of these elements should be the same as the height of the ul.

By doing this, any element that doesn't fit on the first line will wrap onto the second, but since overflow is set to hidden, they simply will just not show.

like image 43
Wex Avatar answered Oct 21 '22 13:10

Wex


I know this is an old thread, but I thought it deserved a proper answer to what you were asking for. Since you are using Modernizr, we can default to inline-block, but detect when flexbox is available and override (using good ol', or good new, progressive enhancement). To get this to work, you much switch #admin-links and #common-links. Below is the code, and it works in IE6+. A demo is also available.

HTML

<div id="wrapper">
    <div id="navigation">
        <ul id="admin-links">
            <li>
                <a href="#">Important Link</a>
            </li>
            <li>
                <a href="#">Important Link</a>
            </li>
        </ul>
        <ul id="common-links">
            <li>
                <a href="#">Important Link</a>
            </li>
            <li>
                <a href="#">Important Link</a>
            </li>
            <li>
                <a class="omittable" href="#">Omittable Link</a>
            </li>
            <li>
                <a class="omittable" href="#">Omittable Link</a>
            </li>
            <li>
                <a class="omittable" href="#">Omittable Link</a>
            </li>
        </ul>
    </div>
    <div id="content">
        <p>Hello world.</p>
        <p>This is supposed to be content.
            But only thing we care is the menu (Sorry about that.)
        </p>
        <p>Page width decreases, some items magically disappear.<br />
            Which is <strong>intended</strong>.<br />
            You can do that by pulling the frame bars around.
        </p>
    </div>
</div>

CSS

#wrapper {
    background: #eee;
    width: 100%;
    min-width: 450px;
    max-width: 700px;
    margin: 0 auto;
}
#navigation {
    height: 40px;
    background: #f00;
    width: 100%;
    overflow: hidden;

}

.flexbox #navigation {
    -moz-box-align: stretch;
    -moz-box-orient: horizontal;
    -webkit-box-align: stretch;
    -webkit-box-orient: horizontal;
    -moz-box-orient: horizontal;
    -webkit-box-orient: horizontal;
    -ms-box-orient: horizontal;
    box-orient: horizontal;
    -moz-box-align: stretch;
    -webkit-box-align: stretch;
    -ms-box-align: stretch;
    box-align: stretch;
    -moz-box-direction: reverse;
    -webkit-box-direction: reverse;
    -ms-box-direction: reverse;
    box-direction: reverse;
    display: -moz-box;
    display: -webkit-box;
    display: -ms-box;
    display: box;
    float: none;
}

#navigation ul {
    overflow: hidden;
    z-index: 990;    letter-spacing: -4px;

}
#common-links {
    overflow: hidden;
}

.flexbox #common-links {
  -moz-box-flex: 1;
  -webkit-box-flex: 1;
  -ms-box-flex: 1;
  box-flex: 1;

}

#navigation li {


    display: inline-block;
    letter-spacing: normal; height: 40px;
}
#navigation li a {
    padding: 10px;
    display:inline-block;
    *display: inline;
    zoom: 1;
    background: #0c0;
    outline: solid 1px #0c0;
}

#navigation a.omittable {
    background: #0f0;
}

#admin-links {
    float: right;
}
.flexbox #admin-links {
    float: none;
}
#admin-links ul {
    white-space: nowrap;
}
like image 190
Jason T Featheringham Avatar answered Oct 21 '22 15:10

Jason T Featheringham


If you want to use new features in old browsers, you are going to need to use js to fix it up. If you write a fallback for IE in CSS, you might as well use the same code in every other browser.

It might be worth reading http://oli.jp/2011/css3-flexbox/ and http://www.xanthir.com/blog/b4580 as well for a few reasons why flexbox is unlikely to catch on – the CSS templating module seems to be a much better solution.

like image 1
Rich Bradshaw Avatar answered Oct 21 '22 14:10

Rich Bradshaw