简体   繁体   中英

How to get the browser border to lock to a div when resizing?

I'm looking at this 3 fixed-column CSS layout on http://www.vanseodesign.com . I want to use this layout however I'd like to change the way it behaves when I resize the browser.

When the browser is open nice and wide the columns are centered nicely on the page:

列居中

Then we reduce the width of the browser and it locks to the left side of the left-most column like this:

显示左列

What I'd like to do is change the CSS (or javascript if necessary) so that the browser locks to the left side of the middle column instead when the browser becomes too narrow:

在此输入图像描述

I'm not sure how to achieve this though?? Can anyone suggest how to change the code and most importantly why your solution works?

EDIT:

For those reading this question: I marked Salem Ouerdani's answer as the correct one because he was the first to answer with a solution that worked the particular way I wanted. However, it became clear that people were interpreting the question in slightly different ways. So it is worth reading through because there are some really great answers which might suit your situation better. Please upvote them as such.

Try to modify your container div from this :

#container { width: 960px; margin: 20px auto;}

to this :

#container {
  width: 960px;
  margin: 20px auto;
  position: absolute;
  left: 50%;
  margin-left: -480px; /* half the fixed width */
}

EDIT : Also you need to add this in order to lock to the left side of the center div whenever your browser size is beyond the fixed 960px :

@media (max-width: 960px) {
    #container {
        left: 0;
        margin-left: -240px; /* Primary Sidebar width */
    }
}

UPDATE : As @media (max-width: 480px){} did better solve the issue rather than 960px then I'm adding the related code pen example with the final solution :

>> Codepen sample code

Update 2015-08-03 01:59 +0000

Reading your comment on another answer about staying centered until the left edge of the centered column meets the browser edge made things much clearer.

This will keep the middle column centered until the browser is as large as the column, then it will stick to the left edge of the column.

html, body {
    margin:0;
    padding:0;
}

@media (max-width: 480px) {
    #container {
        margin-left:-240px;
    }
}

@media (max-width: 960px) and (min-width:481px) {
    #container {
        margin-left:calc( (960px - 100%) / -2 );
    }
}

Original anwser

Pure css. The values of "960" and "720" should be adjusted to account for body margin. Works under Firefox, no guarantees elsewhere. Using calc() for adaptive negative margin based on browser width.

/* fixed negative margin below 720px width */
@media (max-width: 720px) {
    #container {
        margin-left:-240px;
    }
}

/* adaptive negative margin vetween 720px and 960px width */
@media (max-width: 960px) and (min-width:721px) {
    #container {
        margin-left:calc( (960px - 100%) * -1 );
    }
}

Preview

截图 -  20150803-040729-004115-mod.png

Revised Solution (based on OP comment )

Solution by @spenibus is the best and I recommend that. The solution does not work with browsers <= IE9 (IE9 only partially supports it). If you wish to make it cross browser compatible, then I suggest using javascript to manually set the scroll.

Fiddle : http://jsfiddle.net/dp7gwcn5/4/

$(function () {
    $(window).resize(function () {
        var width = $(window).width();
        if (width <= 960) {
            if(width <= 480) $(document).scrollLeft($('#content').offset().left);
            else $(document).scrollLeft((960-width) / 2);
        }
    });
});

Old Solution

Solution #1 (Scroll: Do not hide anything, just cling)

If you wish to keep the sidebar still accessible by scrolling but only make the browser's left edge stick to the left edge of your main content #content . Then manipulate the scroll

Fiddle : http://jsfiddle.net/dp7gwcn5/ . The fiddle will let you change the size of your preview window, as soon as you shrink it enough to hide the secondary sidebar the window clings to the left edge of #content

$(function(){
    $(window).resize(function(){
        if ($(window).width() < 720) {
            $(document).scrollLeft($('#content').offset().left);
        }
    });
});

Note : The width 720 was given based on the widths you have set on your sidebars and conents, you can modify it to be calculated on the fly if you wish.

Solution #2 (Static: Hide primary sidebar)

If you wish to hide the primary sidebar then simply use a media query to hide the primary sidebar when your window size is small

Fiddle : http://jsfiddle.net/dp7gwcn5/1/

@media all and (max-width:720px) {
    #primary {
        display:none;
    }

    #container {
        width:720px;
    }
}

Solution #3 (Dynamic: Hide primary sidebar)

Solution #2 is static and there is not much you can do about it, however, if you wish to compute the widths on the fly and hide the side bar, use a script

Fiddle : http://jsfiddle.net/dp7gwcn5/2/

Script

$(function(){
    $(window).resize(function(){
        if ($(window).width() < 720) $('#container').addClass('small');
        else $('#container').removeClass('small');
    });
});

CSS

#container.small {
    width:720px;
}

#container.small #primary {
    display:none;
}

My Suggestion

My suggestion is to use Solution #1 if you do not wish to make it mobile compatible. If you wish to make it mobile compatible I suggest using Solution #2 with a menu button to show your primary sidebar.

Note : Solution #1 and Solution #3 will work on most browsers. Solution #2 will not work on browsers < IE9

From what I can see, this template uses the margin 0 auto in the container. The way the margin is set up, it centres the "container" which contains all three columns. This means that the content is currently centred by treating each of the three columns as one big one.

This layout is also not responsive. This means that it does not adapt to larger or smaller browser sizes. It has a fixed width and height.

A simple solution is to change the pixel units to %. This will create a fluid layout that will adapt more easily to the browser size as the measurements are based on a portion of the window size instead of having a fixed size.

For example:

body {

width: 50%; } 

No matter what size the browser window is, the body will only account for half the size.

If you are looking to have all three columns visible in the exact same layout or just visible in the browser without scrolling to the side no matter what device or screen size, then you need to use media queries. Media queries are css properties that let you set specific css styles for specific resolutions or screen sizes.

For example:

@media screen and (max-width: 300px) {
    body {
        background-color: lightblue;
    }
}

@media screen and (max-width: 600px) {
    body {
        background-color: purple;
    }
}

In my example (although very rough), the background of the body will be purple up to a small size of 600px. It will then change to blue until a size of 300px.

You can read more about media queries here: http://www.w3schools.com/cssref/css3_pr_mediaquery.asp

1 - remove the margin from your BODY CSS.

2 - wrap all of your html in a wrapper ... all your body content

3 - Define the CSS for the wrapper:

This will hold everything together, centered on the page.

#conatiner{
    margin-left:auto;
    margin-right:auto;
    width:960px;
}
.container {
    max-width: 960px !important;
    margin: 0px auto;
    position: relative;
}

it will work definitely .

html, body
    {
       overflow: scroll !important;
       ms-overflow-y: auto; 
       float: none !important; 
       overflow-y: auto; 
       overflow-x: visible; 
    }  

try this in css or in script use

  function enableScrolling()
        {
            document.body.scroll = "yes"; 
            document.body.overflow="hidden";
        }
@media(max-width : 960px)
{
  #primary{width:0;}
  #content{width:66.7%}
  #secondary{width:33.3%}
  #container{width:100%}
}

Hope this will work for you.

You can do this easily with media queries

At the bottom of your CSS, just add something like:

@media screen and (max-width : 960px) {

    #container {
        margin-left: -260px;
    }

}

When the window size becomes less than 960px, it will shift the container to the left by the width of the left column, leaving it fixed on the left side at the middle column

Here is a fiddle: https://jsfiddle.net/Locwv54q/

EDIT:

With the addition of CSS transitions to make things smoother you can use something like this

At the bottom of your CSS add a media query:

@media (max-width : 960px) {

    #container {
        left: 460px;
        margin-left: -700px;
    }

}

Then during the definition of container earlier in the CSS, use something like this:

#container {
    position: absolute;
    left: 50%;
    width:960px;
    margin-left: -480px;
    margin-top: 20px;
    margin-bottom: 20px;
    -webkit-transition: margin-left 1s ease-in-out;
    -moz-transition: margin-left 1s ease-in-out;
    -o-transition: margin-left 1s ease-in-out;
    transition: margin-left 1s ease-in-out;
}

Of course can fiddle with the values/timings to get things exactly as you want, but this general approach works on my end

updated jsfiddle: https://jsfiddle.net/8L5n58jy/

EDIT2:

This should now work as intended

@media (max-width : 480px) {
#container {
    margin-left: -240px;
    left: 0px;
}
}

#container {
position: absolute;
width: 960px;
left: 50%;
margin-left: -480px;
margin-top: 20px;
margin-bottom: 20px;
}

I would suggest to always center the #container with

position: absolute;
left: 50%;
transform:translateX(-50%);

Then when it will only fit the center column and 1 column (max-width: 720px) you fix the position:

@media (max-width: 720px) {
    #container {
        left:240px;
        transition: left 2s;//make it smooth 
    }
}

A plus for the crazy tab resizers would be to add transition to animate the change transition: left 2s; (but thinking about 'normal' users it may not be necessary)

fiddle

You should definitely read about Twitter-Bootstrap framework, bro:

<div class="container">
    <div class="row>
        <div class="col-sm-3">
            <h2>Left</h2>
        </div>
        <div class="col-sm-6">
            <h2>Center</h2>
        </div>
        <div class="col-sm-3">
            <h2>Right</h3>
        </div>
    </div>
</div>

would do your work, as it is RESPONSIVE. Just saying!

Why not use Bootstrap to create the columns and use the col-sm- or the col-xs- to pull the middle container into place?

Here is the example at the Bootstrap Website

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM