A New Flexible Solution To A Responsive Layout Problem

A couple of weeks ago I talked about a problem I was having in a responsive layout along with my attempted solution to the problem. If you remember that solution wasn’t something I liked due to its inflexibility.

Fortunately in the days since I did work out a solution that is flexible and one I’m happy with. I thought I would share it with you.

Here’s a new demo showing the problem and my new working solution.

Screenshot showing single and 2 column layouts as part of a responsive design

A Reminder of the Problem and Attempted Solution

If you didn’t read the previous post you may want to click the link a couple paragraphs up for the details of the problem and the partial solution I had come up with.

If you did read that post then the image above will look familiar. It’s the before and after of what I was trying to achieve. Both the single and 2 column layout are easy enough to create, though they wanted different html structures and keeping the html the same is a design constraint of responsive layouts.

While I found a way to make both layouts happen, my solution relied on adding a top margin to one of the boxes in the sidebar. The vertical location of the rss (and consequently the series) box was thus dependent on setting that margin

Unfortunately that margin would likely need to change across pages and so the solution was less than flexible.

What I needed was a solution where the vertical location of the rss and series boxes could change dynamically as the height of the post title and post meta boxes changed.

Screenshot showing partial solution with sidebar boxes appearing too high and ignoring location of the post meta box

Current Working Solution

I opened the demo for the last post and began staring at the the example you can see in the image above.

The problem was that when floating the rss box to the left (with the article floated to the right) the rss box was sitting at the top if its container or in this case just below the header.

Because the post meta box was located in a different container (the article) it didn’t affect the location of the rss (or series) box. Having both in the same container seemed like a good approach to a solution.

Step 1

I toyed with the idea of placing the rss and series boxes inside the article, but I knew they didn’t belong there. My eureka moment was to ask myself why not wrap the article, rss, and series boxes inside a new wrapping container.

I used a div since this container was presentational only, set it’s width to the column width, and floated it right. Everything inside this wrapper was allowed to remain at 100% width and I set the comments to a reduced width and floated it to the right as well.

You can see where this left me in the image below.

Step 2

Of course I still needed to float some of the boxes so they would display where I wanted.

My initial thought was to float the article to the right and the rss and series boxes to the left and hope the new container would do all the work.

It didn’t and I was left with the same situation I had without the new wrapper.

I tried taking the float off the article, but as expected that didn’t work either. The rss and series boxes stayed in the left column, but were below the article.

However it did make me wonder what might happen if I floated the bottommost element in the article, the content.

Floating the content to the right instead of the entire article turned out to be the solution. The rss box moved up in the sidebar, but not to the very top of the wrapping container. It sat just below the post meta box, which was exactly where I wanted it.

The reason this worked is because it’s only the content being floated to the right, instead of the entire article. The sidebar boxes will move up as far as they can, but that’s only as far as the top of whatever boxes have been floated to the right.

Screenshot of partial solution showing new wrapping container around article, rss, and series boxes

Final Solution

Once I saw this it was only a matter of finishing things by floating the post meta box to the left, adjusting its width, and giving it a negative left margin like I had done in my previous attempt at a solution.

To make sure this solution really did work I played around with the heights of both the post title and post meta boxes and the location of the rss box changed dynamically.

Below is the code behind this solution. Unlike the last demo I used html5 semantics here like I’m using on the real site. This isn’t the exact code I’m using for the real site, but the basic structure is very close.

The html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="container">
  <header class="box header">Header</header>
    
  <div id="wrapper">
    <article class="article">
      <div id="title" class="box title">Post Title</div>
      <aside id="meta" class="box meta">Post Meta</aside>
      <section id="content" class="box content">Post Content</section>
    </article>
    
    <aside id="rss" class="box rss">RSS</aside>
    <aside id="series" class="box series">Series Links</aside>
  </div>
    
  <div id="comments" class="box comments">Post Comments</div>
  <footer class="box footer">Footer</footer>
</div>

The css below is a simplified version of the css in the demo. I’ve removed some arbitrary code like the outlines and heights of each box.

The values for the widths and margins below are somewhat arbitrary as well, but they’re included so you can see which boxes need a width other than 100% and which boxes use negative margins to position them in the sidebar.

The main thing to note is which boxes are floated and in what direction.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#wrapper {
  width: 65%;
  float: right;
}

#meta {
  width: 52%;
  float: left;
  margin: 0 0 0 -56%
}

#content {
  float: right
}

#rss {
  width: 51%;
  float:left;
  margin: 2% 0 0 -54%;
  clear: left
}

#series {
  width: 51%;
  float:left;
  clear: left;
  margin: 2% 0 0 -54%
}

#comments {
  float:right;
  width: 65%;
}

Ultimately the solution called for a new wrapper and more fine-grained floating than my previous attempt.

Floated right are the new wrapper div, the post content, and the comments below the article. Floated left are the post meta, rss, and series boxes. The rss box is also set to clear: left.

Feel free to check the demo and play around.

Scrrenshot showing final solution for the 2 column layout

Summary

Once again I hope walking through a problem I faced and how I solved it has helped you see into my process a little and help you work out a problem of your own.

A few takeaways.

  • The solution came to me after taking some time away from thinking about the problem, often a good idea when you’re stuck.
  • After some time away, the solution came to me by staring at a partial solution and specifically defining why it wasn’t working
  • In redefining the problem specifics I was able to see a new approach (the wrapping container) to follow
  • Following this new approach and some trial and error led me to the final solution

Again I hope this look into my thought process is helpful.

I also hope this post, my previous attempt at a solution, and my post on rearranging boxes has helped you see how important your html is going to be when working with responsive layouts.

Download a free sample from my book, Design Fundamentals.

2 comments

  1. Good solution! I’m glad you posted this up, I’ve been curious how you solved this issue. I had been playing around with the CSS3 box-ordinal-group property to reorder the HTML source. However, I ran into some odd issues with the height of child elements within the container set to display:box. I set up a jsfiddle here – http://jsfiddle.net/bjankord/2EKQv/ I think it’s important to share the issues we come across when working with RWD so we can learn from each other and progress.

    • Thanks Brett. I agree it’s important to share the issues we’re finding. Weird about the height of the child elements inside the flexbox container. Did you figure out what was going on or find a workaround?

Leave a Reply

Your email address will not be published.

css.php