Responsive wrapper for list - javascript

I am trying to make a responsive wrapper. However, I am having issues determining the right height of it. It's basically a list and when the list gets thinner, its children get fatter.
Here is the jsfiddle. Notice doesn't reproduce the problem when you resize the output window, since it just let's the list go out of view. In my actual application, the list stays entirely inside the screen.
This is my attempt, with jQuery:
if ($(window).width() < 500) {
$(".wrap").css("height", 100 * $(".list li").length);
$(".wrap-list").css("height", 87 * $(".list li").length);
} else {
$(".wrap").css("height", 70 * $(".list li").length); // every item has 70px height, I guess!!!
}
However these hardcoded values are error-prune, since I just figured them out with my eyes in my machine. Any ideas please?

If I understand correctly, you'd like for the list items to get taller as the screen width gets smaller. Best practice is to use CSS media queries, no JS needed:
label {
padding: 10px;
}
#media only screen and (max-width:500px) {
label{
padding: 25px 10px;
}
}
http://jsfiddle.net/daCrosby/cmfL2643/2/

Related

Scroll both columns as one

My app has two columns, left side being a textarea, while the right side is the result calculated from the text area. But my result column would overflow the fixed window, while textarea would scroll by default.
So I've tried to set both the whole row and its parent to overflow: auto, which let me scroll when I've got enough input, but at the expense of having my separator not full height as well as having a delay after I've wrote into my textarea, before the dix snaps into a bigger height...
My final solution was to use JS & Jquery to check when content is overflown, to alternate between height: auto when it is and height: 100% when its not. That also kinda worked, but with wonky delays yet again...
const editor_js = document.querySelector('.editor');
const $editor = $('.editor');
$('.input').bind('input propertychange', function() {
console.log('Textarea changed');
if(editor_js.offsetHeight < editor_js.scrollHeight){
$editor.css("height", "auto");
}
else{
$editor.css("height", "100%");
}
});
Anyways I am at my wits end. I just want to have my columns consistently scrollable as one entity, while keeping the separator full height at all times. Hope you can give me some suggestions. If you want to directly do some attempts at my app, here's the link
The simplest way for you to get that effect would be to add that vertical border as a pseudo element on the parent. When I say simple, I mean it would be easy to set it and forget it. CSS would deal with it and it would be independant of the size
I think your best option will be to calculate the height of your text area in javascript and set the css style to it.
Then, Make sure you have the following css:
textarea.col-9.input {
overflow: hidden !important;
}
.main-body .editor {
overflow: scroll !important;
}
.col-lg-5.col-md-7.col-sm-8.main-body {
overflow: hidden;
}
I've tried it in Chrome's developer tools and it works well.

Auto re-size container if inner elements too small

I have container, which is re-sizable and contains inner elements <div>, which can be placed in any order and I can add them to container any amount when amount of them rising, the become smaller. My goal is when inner divs height or width, becomes smaller than 100px then automatically re-size container.
There can be more than one element smaller than 100px. When container re-sizes, all elements become bigger depending of percents of their width.
Problem: when there is more than one small element, they send many events to container, I want to send one request to container to re-size if there is possibility that it is enough to make all element enough size.
I tried to watch width, but it sends to many requests.
scope.$watch(function () {
return element.width();
}, function (oldval, newval) {
clearTimeout(containerCtrl.resizedFinished);
containerCtrl.resizedFinished = setTimeout(function () {
console.log("New Value=" + newval);
if (newval < 100)
scope.resizeContainer(element.width());
}, 100);
});
Maybe someone can give me any suggestions?
I use Angular, jquery base module, js.
I think you try to achieve:
draggable components should be minimum of 100px wide
when you drag/drop component into container, all components should shrink, so that they fit inside container
when components cannot get any smaller, container should grow (with 100px for each added component)
Sounds like you could get the styling done with flexbox in css:
.container {
display: inline-flex;
flex-direction: row;
padding: 2px;
min-width: 500px;
height: 120px;
background-color: yellow;
}
.component {
background-color: grey;
flex: 0 1 200px;
min-width: 100px;
height: 50px;
margin: 2px;
}
That way you do not have to do any watching of components through jQuery.
If the components also should have variable height, and container can have multiple rows, things become trickier. Then you need to be more specific about constraints.
EDIT:
If you cannot use flexbox for IE9, then try:
add event listener to component being dropped inside container (not on resize of individual components)
check (read from DOM) how many components are in container
if (container width - (component width * old number of components)) < 100
then shrinking is not allowed, so expand container
else
loop over each component to shrink them

How to remove clone() rule in Javascript when screen width is smaller than

I've been fiddling around with my navigation menu and decided to add a feature when you scroll down past a certain point the NAV slides down into viewport so that the user doesn't have to scroll back up to the top of the page to navigate. This is something that's become quite popular lately.
So I fiddled around and this javascript did the trick (note that I am not fluent with jquery at all):
jQuery(document).ready(function($){
$(".menu_wrapper").before($(".menu_wrapper").clone().addClass("shrink"));
$(window).on("scroll", function () {
$("body").toggleClass("slidedown", ($(window).scrollTop() > 700));
});
});
Now I read that as ... duplicate or 'clone' (make another) .menu_wrapper element before the original + add the class .shrink to it ... AND only once we've scrolled past 700px, we'll see this duplicate NAV because of the class .slidedown
CSS:
.shrink { position:fixed; top:-400px; left:0; width:100%; border-top: 0px solid #35d3c3; z-index:99999}
.slidedown .shrink { top:0;}
Now this is working 100% and I'm stoked BUT (it's never smooth sailing is it!!!) now I've got a problem when I change my viewport to a screen width less than 767px - YES my website is responsive and this is where my NAV changes to the typical drop down (even without the javascript / effect above) by using css and javascript:
jQuery(document).ready(function($){
$('.menu_wrapper').prepend('<div id="menu-icon">Menu</div>');
$("#menu-icon").on("click", function(){
$("#menu").slideToggle();
$(this).toggleClass("active");
});
});
My problem is that there is now a duplicate dropdown prepended NAV (1 on top of the other), like so:
+ MENU
+ MENU
The one NAV works but the other doesn't ... anyway regardless, when my media query hits 'mobile status' (below 767px) and the NAV prepends to a dropdown, this is when I DON'T want the whole slide-down-effect-clone (first jquery posted above) thing anymore. I want that rule to almost not exist or not apply when I'm below 767px screen width. How can I do this?
I've tried one of the obvious like:
.shrink { display:none}
.slidedown .shrink { display:none}
which almost seems like I've hit the jackpot leaving me only 1 prepended menu:
+ MENU
but nothing happens when I click on it - it doesn't slidedown and show the menu list items.
but I'm thinking like adding a rule within for the javasacript:
jQuery(document).ready(function($){
$(".menu_wrapper").before($(".menu_wrapper").clone().addClass("shrink"));
$(window).on("scroll", function () {
$("body").toggleClass("slidedown", ($(window).scrollTop() > 700));
});
});
that when we get below a width of 767px, we ignore the clone() function / rule etc?
I've done some googling of removeclass etc but because I'm a bonehead at javascript, I'm probably doing it all wrong.
Any help I'd appreciate it?
Since you want to hide that menu based on certain viewport dimensions, why not use a media query?
#media all and (max-width: 766px){
.shrink{ display: none; }
}
or
.shrink{ display: none; }
#media all and (min-width: 767px){
.shrink{ display: block; }
}
(That might not be the best width values or CSS properties to use there, but that should get you started.)
Edit: If you wanted to do the entire thing in javascript, the matchMedia() API is there for you, too.
If the CSS media query approach that ajm posted does not work for you, you could try only executing your code if a media query is met. The code in handleMediaQuery() will only run if the width is above 767px;
//Media query listeners
var mql = window.matchMedia("(min-width: 767px)");
mql.addListener(handleMediaQuery);
handleMediaQuery(mql);
function handleMediaQuery(mql) {
if (mql.matches) {
// Do stuff here that you want done when the query matches
}
else {
// Do stuff here that you want done when the query does not match
}
}
See https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries for more info

jQuery mobile scrolling/page cut off issue on multi page template

Having this strange issue where page/screen is being cut off.
Seems to happen when you click into this screen below (which is shorter) then click back and go into another longer screen. The scrollbar doesn't appear so the page is cut off. Testing in Chrome v36 & iOS Safari.
http://onegreenthing.net/sunsuper/RetirementModeller/Forecast.html#retirement-age
Any ideas?
PS: Resize window so it's mobile like width (e.g. 400px wide)
.the-thing:before {
content: "";
display: block;
height: 0;
padding-top: 56.25%;
}
Smells like psuedo-vertical-centering that isn't recalculated to vanish appropriately if the page's content is naturally taller than the viewport.
Post-comment update - try this:
if( $(document).height() > $(window).height() ) {
$(".the-thing").remove();
}
Post-comment#2 - your main container element has this css (for id='retirement-age'):
.ui-mobile .ui-page {
min-height: 300px;
}
if I pull up my window shorter than 300 - I get the no-scroll thing - not buggy - that's correct.
Ok rookie error :( ..there was page with duplicate id, removed it and fixed the issue.

Dynamic Background Scrolling

Here's a link to what I'll be referring to.
I'm having some trouble getting the background image to work the way I'd like it to.
I want the background to auto resize based on the width of the window, which it is already doing correctly. If you make your window smaller you'll see the background shrink with it.
Here's the issue. If you make your window wide (short) then the background will resize and go too high so you can't see the top of the background anymore (since the background is bottom positioned).
I want the background to be top position when you are at the top of the page, and as you scroll down it will slowly move to be bottom positioned. Sort of like the effect of an Android phone's background when you move left and right. Of course, keep in mind that I still want the background to auto-resize when you make the window smaller.
html {
background-color: #70d4e3;
height: 100%;
}
body {
height: 100%;
}
.background {
margin-top: 45px;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
}
.banner {
margin: 0px auto;
width: 991px;
margin-bottom: -9px;
}
.content {
background: url("http://i.imgur.com/daRJl.png") no-repeat scroll center center transparent;
height: 889px;
margin: 0 auto;
width: 869px;
}
.innerContent {
padding: 30px;
}
<img src="http://i.imgur.com/6d5Cm.jpg" alt="" class="background" />
<div class="banner">
<img src="http://i.imgur.com/JptsZ.jpg" alt="" />
</div>
<div class="content">
<div class="innerContent">
testing
</div>
</div>
Maybe some javascript or jquery would be needed to achieve this.
Well, this was fun, thanks!
I hope you don't mind me taking the liberty to use percentages to make my life a little bit easier and possibly the script slightly more robust since I can reliably use floats with percentages.
What I did is make the layout, html and css comply with the rules you need for the bg to be animated properly, they stayed largely the same from what you had.
Then it was just a question of figuring out the calculations needed with the right properties to figure out the percentage you were from the top, the *20 is actually the amount of space 'left' to fill by the background image in percentages (as the background height is 80%).
They I moved the calculations to a function so I could call that on scroll and on window resize, making sure it's initiated on any event that modifies the window somehow...
Didn't do extensive testing but it worked in Chrome and I'm tired :p
I believe this is what you are looking for:
http://jsfiddle.net/sg3s/RSqrw/15/ See edit 2
If you wanted this the other way arround just make the page background start at the top and modify that:
http://jsfiddle.net/sg3s/RSqrw/14/ See edit 2
Edit:
As a bonus, and since I had never actually written jquery script as a 'plugin', I decided to convert this into one. What I came up with should be easy to implement and use!
http://jsfiddle.net/sg3s/RSqrw/52/ See Edit 3
Functionality successfully tested in Chrome, Firefox 3.6, IE9 + compatibility mode
Edit 2:
Reading the question again checking if I did it right I noticed I didn't quite do what you want, so I updated the link in the first edit which gives you a plugin in which you can have several options for the scrolling background. It retains my 'old' interpetation while also doing what you want... Read comments in code for some extra descriptions.
Edit 3:
As I went to work today I was bothered with the fact that my plugin 'try' was a little bloated. And as you mentioned in the comment it didn't quite fit the requirements.
So I rewrote it to only do what you want and not much more, tested in Chrome Firefox, IE9 +compat etc etc.. This script is a lot cleaner.
http://jsfiddle.net/sg3s/vZxHW/
You can chose to make the background stick to the top or bottom if the height fits in the window. Nothing else, but that is already more than enough to do some pretty cool stuff :p
An exact solution: Fiddle: http://jsfiddle.net/srGHE/2/show/
View source
Thanks for the challenge. See below for the solution, which is complying with all requirements, including recommended yet optional (with steps on how to remove these) features. I only show the changed parts of your page, with an explanation after each section (CSS, HTML and JavaScript):
CSS (changes):
html,body{
margin: 0;
height: 100%;
padding: 0;
}
body{
background-color: #70d4e3;
}
#background { /*Previously: .background*/
/*Removed: margin-top: 45px;
No other changes*/
}
#banner /*Previously: .banner; no other changes */
#content /*Previously: .content; no other changes */
#innerContent /*Previously: .innerContent; no other changes */
Explanation of CSS revisions:
margin-top:45px at the background is unnecessary, since you're absolutely positioning the element.
All of the elements which are unlikely to appear more than once should be selected via the id (#) selector. This selector is more specific than the class selector.
HTML (changes):
All of the class attributes have been replaced by id. No other changes have been made. Don't forget to include the JQuery framework, because I've implemented your wishes using JQuery.
JavaScript (new):
Note: I have added a feature which you didn't request, but seems logical. The code will automatically reserve sufficient margin at the left side of the window in order to always display the background. Remove anything between the marked comments if you don't want this feature.
$(document).ready(function(){
//"Static" variables
var background = $("#background");
var marginTop = parseFloat(background.css("margin-top")) || 0;
var bannerWidth = $("#banner").width(); /*Part of auto left-margin */
var extraContWidth = (bannerWidth - $("#content").width())/2; /*Same as above*/
function fixBG(){
var bodyWidth = $("body").width();
var body_bg_width_ratio = bodyWidth/1920;
var bgHeight = body_bg_width_ratio * 926; //Calcs the visible height of BG
var height = $(document).height();
var docHeight = $(window).height();
var difHeight = bgHeight - docHeight;
var scrollDif = $(document).scrollTop() / (height - docHeight) || 0;
/*Start of automatic left-margin*/
var arrowWidth = body_bg_width_ratio * 115; //Arrow width
if(bodyWidth - bannerWidth > arrowWidth*2){
$("body > div").css("margin-left", "auto");
} else {
$("body > #banner").css("margin-left", arrowWidth+"px");
$("body > #content").css("margin-left", (arrowWidth+extraContWidth)+"px");
}
/*End of automatic left-margin*/
if(difHeight > 0){
background.css({top:(-scrollDif*difHeight-marginTop)+"px", bottom:""});
} else {
background.css({top:"", bottom:"0"});
}
}
$(window).resize(fixBG);
$(window).scroll(fixBG);
fixBG();
});
Explanation of the JavaScript code
The size of the background is determined by calculating the ratio of the background and document width. The width property is used, because it's the most reliable method for the calculation.
Then, the height of the viewport, document body and background is calculated. If applicable, the scrolling offset is also calculated, to prepare the movement of the background, if necessary.
Optionally, the code determines whether it's necessary to adjust the left margin (to keep the background visible at a narrow window).
Finally, if the background arrow has a greater height than the document's body, the background is moved accordingly, taking the scrolling position into account. The arrow starts at the top of the document, and will move up as the user scrolls (so that the bottom side of the arrow will be the bottom of the page when the user has fully scrolled down). If it's unnecessary to move the background, because it already suits well, the background will be positioned at the bottom of the page.
When the page has finished loading, this functionality is added to the Resize and scroll events, so that the background is always at the right location.
If you've got any other questions, feel free to ask them.
well, I'm not sure if I understand you and why do you want to do that, but you can try adding 2 backgrounds (see http://www.css3.info/preview/multiple-backgrounds/ ), one with the top bg and another with the bottom bg but I think that if the page is not too long it will cause issues, so the other answer with pure CSS is as follows: first add 3 horizontal divs with 100% width. Top div will have your top bg and its height, middle div will be transparent and auto height and bottom div will have your bottom bg and its height. All divs will have a 0 z-index. Then create a higher z-index div to act as a container and you'll be set. If I understand your question right, that's the close I can think of to achieve that. This being said, I'm pretty sure you can do this with JQuery with way better results
Using jQuery I was able to give you what I think you're asking for:
$(window).scroll(function() {
var h = Math.max($(document).height(), $(window).height());
var bottom = h - $(".background").height() - $(window).height();
$(".background").css("top", (($(window).scrollTop() / h) * bottom) + "px");
});
EDIT: Forgot to account for the way scrollTop reports position.
Or maybe:
.background {
margin-top: 45px;
max-width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
max-height: 100%;
}
I reccomend using jQuery Background Parallax
http://www.stevefenton.co.uk/Content/Jquery-Background-Parallax/
The function is as simple as
$("body").backgroundparallax();
Ask if you don't get it to work.
#abney; as i understand your question may that's you want http://jsfiddle.net/sandeep/RSqrw/60/
you need only css for this:
#background {
position: fixed;
width: 100%;
height:100%;
top: 0;
left:0;
z-index: -1;
}
The solution to your issue is a nice little lightweight plugin by Scott Robin. You can get more info, download it, and make your life easier for all of your projects by visiting his project page here.

Categories

Resources