Scrolling two containers with one scrollbar - html

I'm trying to control two containers using only one scrollbar. I have a large container that I shift (using CSS translations) to reveal another container that is sticky to the screen and to the right side. You can see my experiment here:
http://codepen.io/anon/pen/ipaCI
What I want is to use only the outer scrollbar (which controls the big and large div) to scroll both. I'm not looking for any synchronized scrolling, I want the scrollbar to first scroll the small container to the right, and when it's reached the end I want it to scroll the big container to the left.
I've experimented with trying to set a overflow-y: scroll on the body that contains both of these - but I can't seem to control the one on the right. Is it because it's fixed? If I make it positioned absolute it just follows like part of the page - which is not the desired effect.
Has anybody successfully implemented this kind of situation?

I have searched for plugins to do this but was unable to find any.
I've come up with a solution myself using jquery:
var $window = $(window),
$panel = $('.right-panel'),
windowPos = $window.scrollTop(),
scrollPos = $window.scrollTop(),
maxPos = $('.panel', $panel).height() - $window.height();
$window.on('scroll.panels-handler', function() {
var scrollDelta = $window.scrollTop() - windowPos;
windowPos = $window.scrollTop();
scrollPos += scrollDelta;
if (scrollPos < 0) {
scrollPos = 0;
} else if (scrollPos > maxPos) {
scrollPos = maxPos;
}
$panel.scrollTop(scrollPos);
});
I added a min- and max-scroll value for the container. Basically - it will always scroll the sidebar first - until it's reached its end - and then only the main window.
I couldn't figure out how to scroll only the sidebar (the main always scrolls) - but I'm satisfied with the solution.
See original codepen for a working demo
http://codepen.io/anon/pen/ipaCI

Related

Bootstrap - match vertical column heights that are not in a row

I've a rather complicated website design I'm working on. I have the following 4 containers (I call them that, but they don't have the .container class)
In a wide screen layout:
In a narrow screen layout:
The issue I'm having is matching the total height of the white, grey and yellow containers with the blue container on a wide screen layout:
The grey and yellow containers are in a .row div, so adding the style { display: inline-flex } makes them the same height on a narrow screen layout:
However, this moves them completely to the side in the wide screen layout and this wouldn't match the combined white, grey and yellow containers with the blue container:
I tried a JavaScript solution as #Paulie_D recommended.
$(window).load(function () {
NormalizeHeights();
});
window.onresize = function (event) {
NormalizeHeights();
}
function NormalizeHeights() {
if (window.innerWidth >= 768) {
var carousel = $(".carousel-container");
var dashTop = $(".dash-row-top");
var panelLeft = $(".dash-row-bottom .panel-lightgray");
var panelRight = $(".dash-row-bottom .panel-yellow");
var carouselHeight = parseFloat(carousel.css('height'));
var dashTopHeight = parseFloat(dashTop.css('height'));
var panelLeftHeight = parseFloat(panelLeft.css('height'));
var panelRightHeight = parseFloat(panelRight.css('height'));
var dashBottomHeight;
if (panelLeftHeight > panelRightHeight) {
dashBottomHeight = panelLeftHeight;
}
else {
dashBottomHeight = panelRightHeight;
}
if (carouselHeight > (dashTopHeight + dashBottomHeight)) {
var difference = carouselHeight - (dashTopHeight + dashBottomHeight);
panelLeft.css("height", (dashBottomHeight + difference));
panelRight.css("height", (dashBottomHeight + difference));
}
else {
var difference = (dashTopHeight + dashBottomHeight) - carouselHeight;
carousel.css("height", (carouselHeight + difference));
panelLeft.css("height", (dashBottomHeight));
panelRight.css("height", (dashBottomHeight));
}
}
}
This works, sort off, but it's extremely unlikable in my estimation.
I had a similar problem and the solution I found was rather ugly but worked for me.
I used divs that would clear formats BUT would their presence would be conditioned (using ng-if). Programmatically, I measured the width of the screen and set a threshold. If the width was above the threshold, I set the location of the divs, measured the height of the contents and, when applicable, forcefully changed the height of all the relevant divs to look the same (note that you would need to set this size update AFTER A TIMER is fired to let the rendering to complete).
Hope this gives you some ideas and remember: I was the first to call this ugly.

How to make bar chart not be crushed with a lot of data in google bar chart?

Using a bar chart: https://developers.google.com/chart/interactive/docs/gallery/barchart when you have a lot of data, it crushes the bars to be very thin and the text to overlap each other. What options are there to get the data to render in the container properly (maybe guarantee each bar to be of a certain height if possible)? I want to avoid explicitly setting the height to say "1000px", then looking at the bar chart to determine whether it is scrunched up or not.
You can calculate a height for your BarChart dynamically, based on the number of rows of data in your DataTable:
// set inner height to 30 pixels per row
var chartAreaHeight = data.getNumberOfRows() * 30;
// add padding to outer height to accomodate title, axis labels, etc
var chartHeight = chartAreaHeight + 80;
var chart = new google.visualization.BarChart(document.querySelector('#chart_div'));
chart.draw(data, {
height: chartHeight,
chartArea: {
height: chartAreaHeight
}
});

Resizing floated first div's based on second floated div contents?

I want to have to floated columns side-by side. If second column has contents then the first column should resize its content based on the second column, is that possible with CSS? Widths are not defined.
It's possible using javascript but not with straight CSS. Here are some ways to do it:
Using javascript:
var rightDiv = document.getElementById("straightJ2");
var rightWidth = rightDiv.clientWidth;
var leftDiv = document.getElementById("straightJ1");
if($('#straightJ2').text() || rightDiv.hasChildNodes()) {
leftDiv.style.width = rightWidth + "px";
}
Or more minimal (and possibly overwhelming/hard to follow) javascript:
if($('#minimal2').text() || $('#minimal2').firstChild) {document.getElementById("minimal1").style.width = document.getElementById("minimal2").clientWidth + "px";}
Using jQuery:
if($('#secondColumnId').html() != '')
{
$('#firstColumnId').width($('#secondColumnId').width());
}
Each of these check the second div for text or a child element and change the width of the first if one of those conditions is met
All examples can be found used in this jsFiddle

Canvas dimensions based on outer div measurements (js?)

I am having a bit of a layout nightmare. I've been trying for days to fix it on my own but now it's come to this....
http://jsfiddle.net/Osceana/yQ3As/2/
I am just trying to get the canvas to span the entire length of that timeline, and I want it to end just above the "All Sites" div, regardless of the window it is moved to. I cannot seem to achieve this though. I've tried in javascript to no avail.
$("#chart").height(
canvasHeight);
$("#chart").width(
timelineWidth);
P.S. The timeline is supposed to have a left-margin which I implement in js:
$("#timeline").css(
"margin-left", namesWidth);
^ this shows up in MY project, but not here on jsfiddle for some reason. However in my project the left-margin seems to be causing horizontal overflow. I just want that timeline to be moved over enough for the names, then it spans the entire rest of the horizontal length of the screen. I've set the CSS for the width at 100%, 92%, etc., and my results are always strange. Is it because of the left-margin the percentage isn't working?
timeline CSS:
#timeline {
font-size:15px;
color:black;
font-family:Calibri;
text-align:center;
margin-top:60px;
width:100%;
}
#timeline td {
width: 4%;
}
timeline js:
var namesWidth = $("#names").width()
$("#timeline").css(
"margin-left", namesWidth);
*Thank you so much for any and all insight. I hope I'm not asking too much.
Live Demo
Editor
You didn't have your fiddle set to use jQuery. Below should get you close to what you need.
var $chart = $("#chart"),
spacing = 40,
canvasHeight = $("#company").position().top - $chart.position().top - spacing,
windowWidth = $(window).width(),
namesWidth = $("#names").width();
$chart.width($("#timeline").width());
$chart.height(canvasHeight);
$("#timeline").css("margin-left", namesWidth);
$chart.css("margin-left", namesWidth);
// change on resize
$(window).resize(function () {
canvasHeight = $("#company").position().top - $chart.position().top - spacing;
$chart.height(canvasHeight);
});

Get the default height of a scroll bar

What is the default height of a scroll bar(Horizontal)?
I couldn't find the document online.
UPDATED: Can we write a javascript function to get it? Please don't down vote it. It is hard to get it.
Thank you.
Found this here: How can I get the browser's scrollbar sizes?
function getScrollBarWidth () {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild (inner);
document.body.appendChild (outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild (outer);
return (w1 - w2);
};
alert( getScrollBarWidth () );
That's going to depend on the clients screen resolution and browser. If you explain why your asking then I might be able to give a better answer.
Whatever the user's computer is set to. There is no hard-and-fast rule on this. For example, on my Ubuntu machine, the default scroll bar size is 0 - instead of a conventional scrollbar, it has a scroll line with arrows that appear when the mouse moves near it, and it takes no space on the document. However, on my Windows installation, the scrollbar size is 14 pixels, but I could set it from anything between about 8 and over 500...
Interesting question. My thought is: when a property you are interested in is not readily available, test.
One DOM property I can think of that would be affected by the scrollbar height is the clientHeight of the body (or whatever box has the scrollbar) if you set it to 100%. This is maybe a dumb approach, and not sure how useful it really is, but check it out:
get clientHeight before
expand width of an internal element, wide enough to cause a scrollbar
get clientHeight after
subtract
I made a fiddle of this. Like I said, not sure how useful this approach could be in real life, but maybe it's a start on something.
http://jsfiddle.net/brico/t6zMN/