简体   繁体   中英

Dynamic width animation based in CSS Media Query

I have two divs:

<div class="map-ctn"></div>
<div class="list-ctn"></div>

And the Media Queries:

@media only screen and (min-width: 1281px) and (max-width : 1824px) {
    .map-ctn { width: 80%; }
    .list-ctn { width: 20%; }
}

@media only screen and (min-width: 961px) and (max-width : 1280px) 
{
    .map-ctn { width: 75%; }
    .list-ctn { width: 25%; }
}

I want to start the .list-ctn div with 0% and the .map-ctn with 100% and animate the .list-ctn do X% and .map-ctn to Z% based on the Media Query active.

EDIT:

The animation should occur on a jQuery event (form submit).

So maybe I need to control the divs using jQuery but using the Média Query info to animate the width based on the width of each div.

It has to work from IE9+, Safari, Chrome and Firefox.

Yes there is a way. By using CSS3 transitions it is possible to animate the change. In this example the jQuery submit listener adds a class of submitted to the two div s. The media query rules in effect then become active. Please take note that this only works if there is an initial width defined for the element and not just the default. This will also not work in IE 9 or lower.

EDIT: In response to your update I have added the jQuery submit listener. I assume that once the form is submitted that you will not want to have the elements switch back to their initial state.

To make it easier to visualize what rules were in force I added some color.

 $(document).ready(function(){ $('#target').submit(function(event){ event.preventDefault(); $('.map-ctn').addClass('submitted'); $('.list-ctn').addClass('submitted'); }); }); 
 .map-ctn{ height: 50px; width: 100%; background-color: green; transition: width 5s; } .list-ctn{ height: 50px; width: 0%; background-color: blue; transition: width 5s; } @media only screen and (min-width: 401px) and (max-width : 600px) { .map-ctn.submitted{ background-color: lightgreen; width: 80%; } .list-ctn.submitted{ background-color: lightblue; width: 20%; } } @media only screen and (min-width: 200px) and (max-width : 400px) { .map-ctn.submitted{ background-color: darkgreen; width: 75%; } .list-ctn.submitted{ background-color: darkblue; width:25%; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="map-ctn"></div> <div class="list-ctn"></div> <form id="target"> <input type="submit" value="Submit"> </form> 

 setTimeout(function() { $('.mapexpanded').removeClass('mapexpanded'); }, 300); 
 And the Media Queries: @media only screen and (min-width: 1281px) and (max-width : 1824px) { .map-ctn { width: 80%; } .list-ctn { width: 20%; } } @media only screen and (min-width: 961px) and (max-width : 1280px) { .map-ctn { width: 75%; } .list-ctn { width: 25%; } } .map-ctn { width: 60%; } .list-ctn {width: 40%; } .map-ctn, .list-ctn { transition: width 1s ease-in-out; height: 300px; background-color: red; margin-bottom: 10px; } html body .mapexpanded .map-ctn { width: 100%; } html body .mapexpanded .list-ctn { width: 0%; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="mapexpanded"> <div class="map-ctn zerowidth"></div> <div class="list-ctn zerowidth"></div> </div> 

I used JQuery here only to shorten the JS a bit; not because it makes heavy use of any JQuery libraries. The animation going on here is all CSS.

You didn't have a width for viewports that didn't match your queries, so I just added 60%/40%. It's possible you actually wanted something else; feel free to tweak it. It will shift automatically when the browser is resized. Also, you can likely shorten the setTimeout call, or replace it with requestAnimationFrame .

I'm not sure this is what you're after, but it seems pretty enough to me. I took an approach that relies on rather new features (such as flex and classlist) but considering you are using media queries, that shouldn't be quite the problem.

http://jsfiddle.net/BramVanroy/bf8895wq/5/ or fullscreen demo (make sure to make the window wide enough!)

1. Add init class to elements:

<div class="map-ctn init"></div>
<div class="list-ctn init"></div>

2. Remove that class on load with plain JS:

var init = document.getElementsByClassName("init");
while (init.length) {
    init[0].classList.remove("init");
}

3. Make sure you add a transition to flex-grow in CSS:

transition: flex-grow 1200ms;

4. Now your media queries only have to hold one line:

@media only screen and (min-width: 1281px) and (max-width : 1824px) {
    .map-ctn {flex-grow: 4;}
}
@media only screen and (min-width: 961px) and (max-width : 1280px) {
    .map-ctn {flex-grow: 3;}
}

Considering your edit: http://jsfiddle.net/BramVanroy/bf8895wq/6/

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