Question

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?

Was it helpful?

Solution

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>

OTHER TIPS

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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top