Question

The main content of my webpage has two columns, this content will be compressed when the viewport gets smaller, and the 'columns' will be displayed below one another when the viewport becomes even smaller.

It also has a right sidebar. The sidebar has to be fixed width (download buttons, social buttons, etc). It consists of two parts:

  • the first part needs to go above the main content when the viewport becomes too small (the download buttons)
  • the second part needs to go below the main content (social buttons)

I have got most of this going, except that the second part of the right sidebar does not want to float up all the way when the 'columns' are below one another. The code I have so far:

<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0" />
<style>

#minmax {
    max-width: 940px;
    min-width: 280px;
    margin: 0 auto;
    background-color: #d0ffd0;
}

.right_sidebar_top {
    clear: right;
    width: 220px;
    float: right;
    margin: 0 0 10px 20px;
    background-color: #c0c0ff;
}

.content_wrapper {
    margin: 0 250px 10px 0;
    background-color: #ffff90;
}

.content_left_col {
    width: 48%;
    margin-right: 4%;
    background-color: #e0ffff;
    float: left;
}

.content_right_col {
    width: 48%;
    background-color: #e0e0ff;
    float: left;
}

.right_sidebar_bottom {
    clear: right;
    width: 220px;
    float: right;
    margin: 0 0 10px 20px;
    background-color: #ffe080;
}

@media only screen and (max-width: 799px) {
    .content_left_col {
        width: 100%;
        margin-right: 0;
    }
    .content_right_col {
        width: 100%;
    }
}

@media only screen and (max-width: 599px) {
    .right_sidebar_top {
        clear: both;
        width: 100%;
        float: left;
        margin: 0;
    }
    .content_wrapper {
        margin: 0 0 10px 0;
    }
    .right_sidebar_bottom {
        clear: both;
        width: 100%;
        float: left;
        margin: 0;
    }
}
</style>
</head>
<body>
    <div id="minmax">
        <div class="right_sidebar_top">Lorem ipsum</div>
        <div class="content_wrapper">
            <div class="content_left_col">Lorem ipsum dolor sit amet,
                consectetur adipiscing elit. Aliquam posuere mauris adipiscing neque
                faucibus ultrices nec nec sem. Praesent venenatis hendrerit arcu, in
                sollicitudin risus convallis faucibus.</div>
            <div class="content_right_col">Lorem ipsum</div>
        </div>
        <div class="right_sidebar_bottom">Lorem ipsum</div>
    </div>
</body>

I have seen another question/solution here that used absolute positioning of the right sidebar, I think that wont work in my case because it needs to be below another right-sidebar element. I have spent about two days trying to figure this out, so I really hope someone can come up with a working approach!

edit:

I expect my target audience to be mostly android-mobile users. For the small amount of desktop users with older browsers I can relatively easy serve an unresponsive 960/12 css, but the solution should work across the popular android browsers.

Was it helpful?

Solution

Using display: table

Here's an option that doesn't use calc, but you'll need to use an additional element that you'll hide and show depending on the screen size: Demo

Add another class to your top sidebar item:

<div class="right_sidebar_top one">Lorem ipsum</div>

Then replace your bottom sidebar item with this:

<div class="right_sidebar">
    <div class="right_sidebar_top two">Lorem ipsum</div>
    <div class="right_sidebar_bottom">Lorem ipsum</div>
</div>

Then use this css outside the media-queries. It hides the top sidebar item and displays the sidebar grouping. Using display: table-cell allows the one div to be a set width, and the content to expand:

.content_wrapper, .right_sidebar {
    display: table-cell;
    vertical-align: top;
}
.right_sidebar_top.one {
    display: none;
}
.right_sidebar_top.two{
    display: block;
}

Then in your 599px media-query, hide the top sidebar within the grouping and display the single top sidebar item and set everything else back to display: block to act like divs:

.content_wrapper, .right_sidebar {
    display: block;
}
.right_sidebar_top.one {
    display: block;
}
.right_sidebar_top.two {
    display: none;
}

Using calc()

If you can use calc(), this is an option: Demo

This allows the divs to flow exactly how you'd like. May need to make some minor tweaks to get it exactly how you want.

.content_wrapper {
    width: calc(100% - 250px); // keeps the right side at 250px for the right sidebar
    background-color: #ffff90;
    float: left; // allows the two right column divs to float next to it
}

//to clear floats
#minmax:after {
    display: table;
    content:'';
    clear: both;
}

.right_sidebar_bottom {
    float: right;
}

@media-query(max-width: 599px){
    .content_wrapper {    
        width: 100%;
    }
}

OTHER TIPS

I came up with an answer myself, based on the answer from brouxhaha:

From his calc-based answer I figured that the problem was with all the floats not having any 'real size'. So I reused his #maxmin:after idea to make the content area 'opaque'. At the same time this pushes away the sidebar, as if there is now apparently no room next to the content area. To fix this I fiddled with negative margins on the sidebar items, to make them overlap with the 'opaque' content, so they would slide into place. I made it work, an example can be seen here.

Changes in the code (I think this is all):

#minmax:after {
    display: table;
    content:'';
    clear: both;
}

.right_sidebar_top {
    clear: right;
    width: 220px;
    float: right;
    margin-left: -220px;
    background-color: #c0c0ff;
}

.right_sidebar_bottom {
    width: 220px;
    float: right;
    margin-left: -220px;
    background-color: #ffe080;
    clear: right;
}

This is the solution I'll be implementing. I do not like is the use of negative margins however; this solution does not feel like css is helping me to go from requirements to implementation, but more like working around css to get the job done. So if anyone knows a 'cleaner' solution to this problem please post it here so others (like me) can learn!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top