1

I have a ul with the following elements:

<ul class="list-unstyled">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">About Me</a></li>
    <li><a href="#">Work</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Blog</a></li>
</ul>

I'd like to reorder the Home element and place it in the middle in certain situations.

When viewing this in a smaller screen, the list will be rendered vertically, following the order specified in the markup.

However, when viewing on a larger screen, the list will be horizontal, and Home will be in the middle (between Work and Contact).

Is this possible to do purely in CSS? or will I need to use JS or JQuery to reorder the <li> elements?

Konrad Gadzina
  • 3,407
  • 1
  • 18
  • 29
miguelarcilla
  • 1,426
  • 1
  • 20
  • 38

2 Answers2

2

This is possible with CSS, but fragile; I think you'd probably be better off using some JavaScript to do it. Basically, you use rules like this:

.list-unstyled li:nth-child(1) {
    /* ...set the position of the Home entry... */
}
.list-unstyled li:nth-child(2) {
    /* ...set the position of the About Me entry... */
}
.list-unstyled li:nth-child(3) {
    /* ...set the position of the Work entry... */
}
.list-unstyled li:nth-child(4) {
    /* ...set the position of the Contact entry... */
}
.list-unstyled li:nth-child(5) {
    /* ...set the position of the Blog entry... */
}

...and a lot of positioning styles. You probably have to make the ul position: relative and then absolutely-position the lis within it.

Here's one of the many ways you could do those positioning styles: Live Copy

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Fragile ul reordering example</title>
  <style>
    /* Put this in the relevant media query... */
    .list-unstyled {
      list-style: none;
      padding: 0;
      margin: 0;
      position: relative;
    }
    .list-unstyled li {
      display: table-cell;
      position: absolute;
      width: 20%;
      text-align: center;
    }
    .list-unstyled li:nth-child(1) {
      left: 40%;
    }
    .list-unstyled li:nth-child(2) {
      left: 0%; /* Just for completeness... */
    }
    .list-unstyled li:nth-child(3) {
      left: 20%;
    }
    .list-unstyled li:nth-child(4) {
      left: 60%;
    }
    .list-unstyled li:nth-child(5) {
      left: 80%;
    }
  </style>
</head>
<body>
<ul class="list-unstyled">
    <li class="active"><a href="#">Home</a></li>
    <li><a href="#">About Me</a></li>
    <li><a href="#">Work</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Blog</a></li>
</ul>
</body>
</html>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

You can use feature of CSS3 called flexbox - the order property, to be precise. You can use nth-child to specify elements to change order for or you can simply give them a class and operate using it. Example:

HTML:

<ul class="list-unstyled">
    <li class="active"><a href="#">Home</a></li>
    <li class="left-element"><a href="#">About Me</a></li>
    <li class="left-element"><a href="#">Work</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Blog</a></li>
</ul>

CSS:

.list-unstyled {
    display: flex;
    list-style: none;
}

.list-unstyled li {
    margin: 5px;    
}

.list-unstyled li.left-element {
    order: -1; /* the default is 0 */
}

Fiddle with this example.

However, be sure to check it's availability on different platforms and make sure it's fine for you. I found out about flexbox as I found this SO answer.

EDIT:

As T.J.Crowder mentioned, it would be good to use prefixes for specific browsers, as only latest releases of some browsers support non-prefixed implemenation. You can check different prefixed versions here.

Check the extended example (the updated fiddle is here). As for my tests in older Firefox (version 20) it looks like it it does not support values less than 0 for order, so I added order values for all elements:

<ul class="list-unstyled">
    <li class="active center-element"><a href="#">Home</a></li>
    <li class="left-element"><a href="#">About Me</a></li>
    <li class="left-element"><a href="#">Work</a></li>
    <li class="right-element"><a href="#">Contact</a></li>
    <li class="right-element"><a href="#">Blog</a></li>
</ul>

<style>
    .list-unstyled {
        display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
        display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
        display: -ms-flexbox;      /* TWEENER - IE 10 */
        display: -webkit-flex;     /* NEW - Chrome */
        display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */
        list-style: none;
    }

    .list-unstyled li {
        margin: 5px;
    }

    .list-unstyled li.left-element {
        -webkit-box-ordinal-group: 0;   /* OLD - iOS 6-, Safari 3.1-6 */
        -moz-box-ordinal-group: 0;      /* OLD - Firefox 19- */
        -ms-flex-order: 0;              /* TWEENER - IE 10 */
        -webkit-order: 0;               /* NEW - Chrome */
        order: 0;                       /* NEW, Spec - Opera 12.1, Firefox 20+ */
    }

    .list-unstyled li.center-element {
        -webkit-box-ordinal-group: 1;   /* OLD - iOS 6-, Safari 3.1-6 */
        -moz-box-ordinal-group: 1;      /* OLD - Firefox 19- */
        -ms-flex-order: 1;              /* TWEENER - IE 10 */
        -webkit-order: 1;               /* NEW - Chrome */
        order: 1;                       /* NEW, Spec - Opera 12.1, Firefox 20+ */
    }

    .list-unstyled li.right-element {
        -webkit-box-ordinal-group: 2;   /* OLD - iOS 6-, Safari 3.1-6 */
        -moz-box-ordinal-group: 2;      /* OLD - Firefox 19- */
        -ms-flex-order: 2;              /* TWEENER - IE 10 */
        -webkit-order: 2;               /* NEW - Chrome */
        order: 2;                       /* NEW, Spec - Opera 12.1, Firefox 20+ */
    }
</style>
Community
  • 1
  • 1
Konrad Gadzina
  • 3,407
  • 1
  • 18
  • 29
  • 1
    Ah, yes, flexbox, +1. Too bad using it in the wild is basically still a couple of years away (not even IE9 has it, and despite the supposed end of XP we're stuck with IE8 for at least a couple of years). If you do use it (and ignore IE8 and IE9 users), be sure to prefix it, as only really, really cutting-edge browsers support it without prefixes. – T.J. Crowder May 05 '14 at 07:13
  • @T.J.Crowder yeah, that's a pitty that such nice feature is not fully supported yet. I've added info about prefixes, thank you. – Konrad Gadzina May 05 '14 at 13:29