Adjust horizontal scrollbar location based on parent div height - css

I'm new to css and not sure how to do this.
I have a parent div that has a fixed height and a child div that has a fixed width with horizontal scroll overflow. The problem is that the child divs horizontal scroll is hidden on the bottom of the div. Is there a way so that the child divs horizontal scroll can be displayed as in the attached picture?
Thanks

My approach with jQuery, take a look at this fiddle!
Explanation
This version is desktop & mobile (Touch) compatible. Here, #scroller a hidden div with a horizontal scroll-bar to capture the scrolling and adjust the #inner div's scroll position.
Maximum horizontal scroll ranges can be different between #scroller & #inner, so I'm mapping from one range to the other.
HTML
<div id="outer">
<div id="scroller">
<div id="expander"></div>
</div>
<div id="inner">
<h1>This is looong text for testing</h1>
</div>
</div>
CSS
#outer {
width: 100%;
height: 300px;
border: 3px solid red;
overflow-y: scroll;
position: relative;
}
#inner {
width: 50%;
height: 700px;
border: 3px solid blue;
overflow-x: hidden;
}
#scroller {
height: 300px;
width: 50%;
position: absolute;
top: 0;
left: 0;
overflow-x: scroll;
}
#expander {
width: 200%;
height: 1px;
}
h1 {
width: 700px;
}
JQuery
$("#outer").on('scroll', function() {
var oTop = $("#outer").scrollTop();
$('#scroller').css('top', oTop);
});
$("#scroller").on('scroll', function() {
var scrollerMax = $(this)[0].scrollWidth - $(this).width();
var innerMax = $('#inner')[0].scrollWidth - $('#inner').width();
$('#inner').scrollLeft(mapRange($("#scroller").scrollLeft(), 0, scrollerMax, 0, innerMax))
});
function mapRange(x, in_min, in_max, out_min, out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

try using position:absolute for the child div.
if you could post the code i can show you how on your specific example

Related

How to float an element next to a possible right scrollbar?

I want my page elements to stay in the same position regardless of whether there's a scrollbar on the right edge or not. I've managed to accomplish this for the main content by giving the body 100vw and by giving the main content a margin-right of the width of the scrollbar. (Assume, for simplicity's sake, that the width of the scrollbar is fixed at 16px.) But I can't figure out how to make content on the right stick to where the scrollbar's left edge will be.
In the example below, the "Right" text should not change position when the scrollbar appears, and all of its text should remain visible without hard-coding its left (since that would have to be changed every time the width of its content changed).
const { style } = main;
setInterval(() => {
// simulating lots of main content
style.height = style.height ? '' : '1000px';
}, 2000);
body {
margin-top: 40px; /* because the "Result" gets in the way */
width: 100vw;
margin: 0;
}
#right {
position: absolute;
right: 0;
}
#right > div {
margin-right: 16px; /* SCROLLBAR WIDTH */
}
#main {
padding-top: 60px;
margin-right: 16px; /* SCROLLBAR WIDTH */
}
#main > div {
text-align: center;
margin: 0;
}
<div id=right>
<div>
Right
</div>
</div>
<div id=main>
<div>
Main content (does not change position)
</div>
</div>
I've tried lots of combinations of float: right, position: absolute, margin-right and right properties on the elements, and tried nesting another container on the right, but nothing gave me the desired result. How can this be achieved?
Use left not right with vw unit and rectify with a translation:
const { style } = main;
setInterval(() => {
// simulating lots of main content
style.height = style.height ? '' : '1000px';
}, 2000);
body {
margin-top: 40px; /* because the "Result" gets in the way */
width: 100vw;
margin: 0;
}
#right {
position: absolute;
left: 100vw; /* all the way to the left */
transform:translateX(calc(-1*(100% + 16px))); /* move back considering 100% of its width and scrollbar width*/
}
#right > div {
margin-right: 16px; /* SCROLLBAR WIDTH */
}
#main {
padding-top: 60px;
margin-right: 16px; /* SCROLLBAR WIDTH */
}
#main > div {
text-align: center;
margin: 0;
}
<div id=right>
<div>
Right
</div>
</div>
<div id=main>
<div>
Main content (does not change position)
</div>
</div>

How to stretch a canvas to page full height with header & footer?

Is there a simple CSS-only solution to make a HTML5 canvas to fill the entire space between a header and a footer?
The height of header and footer is known and fixed, all elements should have 100% width. Key point here is the simplicity of markup and style, and to avoid wrapper divs.
This is my markup:
<div class="header"><p>header</p></div>
<canvas id="content" class="content"></canvas>
<div class="footer"><p>footer</p></div>
While the problem of a full-height div between header and footer seems to be a lot easier to solve, and there are on SO already some very fine answers, i cannot figure a way to get the same with a canvas.
Fiddle: http://jsfiddle.net/h7smdykf/
Do you mean like this?
Edit: Jep, they are right, streching the canvas skrews up your elements. I got a little further with "object-fit" https://www.w3.org/TR/css3-images/#the-object-fit
Using "object-fit" is suggested from https://html.spec.whatwg.org/multipage/scripting.html#the-canvas-element
Edit2: There is still a problem with the vertical alignment. The Circle should be in the middle of the page.
z-Index solves the problem.
var c=document.getElementById("content");
var ctx=c.getContext("2d");
var x = c.width / 2;
var y = c.height / 2
ctx.beginPath();
ctx.arc(x,y,50,0,2*Math.PI);
ctx.stroke();
html, body {
margin: 0;
padding: 0;
}
.header, .footer {
position: fixed;
width: 100%;
height: 48px;
left: 0;
background: lightgreen;
z-index: 1;
}
.footer {
bottom: 0px;
}
.content {
position: fixed;
width: 100%;
height: 100%;
object-fit: scale-down;
background: lightblue;
z-index: 0;
margin: 48 0 48 0;
}
<div class="header"><p>header</p></div>
<canvas id="content" class="content"></canvas>
<div class="footer">footer</div>

Fixed div does not go beyond the screen's right edge

I have a div which has a fixed position. The problem is when the div moves to the right it does not go beyond the screen's right edge. It resizes itself making its width smaller. This does not happen when I give it a fixed width. But I want it to have a fluid width with max-width defined. I do not want it to stick to the right edge by defining right. I want to define the left position and let the excess go out of the screen.
You can see the problem here: http://codepen.io/anon/pen/BjZppJ
Click on the div in the example to see the problem.
HTML CODE
<div> -- RANDOM TEXT HERE -- </div>
CSS CODE
div
{
position: fixed;
left: 0;
top: 0;
padding: 20px;
max-width: 500px;
background: rgba(112,66,102, .1);
}
div.right
{
left: calc(100% - 300px)
}
Add width: 100%; to the div, by doing so it will always try to be 100% the width of it's parent, but since you set the max width, it will not quite get there.
$('div').click(function(){
if($(this).hasClass('right'))
{
$(this).removeClass('right')
}
else
{
$(this).addClass('right')
}
})
div
{
position: fixed;
left: 0;
top: 0;
padding: 20px;
max-width: 500px;
background: rgba(112,66,102, .1);
width: 100%;
}
div.right
{
left: calc(100% - 300px)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>as dfas dfa sdf asdfasd fsdf sdfasdfa sdfasdfasd fasdfa sdfa sdfasdfa sdfasdfa sdfsdf sd</div>
adding width:100% to the style definitions of the div will do the trick.
Default is width:auto and for elements with fixed positions it will try to calculate a width which does not overflow the window dimensions.

Fluid Image 80% width and height relative to its parent vertically and horizontally aligned

Height was not respected on this fiddle
I want the image to have a height and width of 80% relative to its parent, vertically and horizontally aligned. For some reason, it does not work.
HTML:
<div id="menu_header_new_orig">
<img id="menu_logo_orig" src="https://imagizer.imageshack.us/v2/849x565q90/833/uua2.jpg" />
</div>
CSS:
#menu_header_new_orig {
margin-top: 2.5%;
height:40%;
width:100%;
overflow: hidden;
position: relative;
border: 1px solid green;
text-align: center;
}
#menu_logo_orig {
width: 80%;
height: 80%;
position: relative;
}
I have figured it out here, but just in case somebody have better solution.
If I understand you correct :
The parent #menu_header_new_orig own parent must also have a height (obviously 100%)
html, body {
height: 100%;
}
set display to inline, 10% top to get vertical alignment
#menu_logo_orig {
top: 10%;
display: inline;
position: relative;
width: 80%;
height: 80%;
}
Is that what you were heading for? [not really sure] - try to set #menu_header_new_orig height to other things than 40% to get it in another perspective.
forked fiddle -> http://jsfiddle.net/Dmc7j/

Overflow-x: hidden also hides vertical content too

I have a DIV measuring 400px wide, containing two DIVs side-by-side, each with width of 400px and height of 600px. The width of both DIVs is fixed, however the height can vary. I'd like to hide the second DIV and show the first completely, with no scrolling inside the DIV.
My solution, I thought, was to hide the overflow-x. This seems to also hide the y overflow too.
Here's my code:
#schools-sub-nav {
}
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
overflow-x: hidden;
}
#schools-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: purple;
position: absolute;
top: 0;
left: 0;
}
#boards-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: green;
position: absolute;
top: 0;
left: 400px;
}
<div id="schools-sub-nav"> Schools List // Boards List </div>
<div id="schools-container">
<div id="schools-list"> One </div>
<div id="boards-list"> Two </div>
</div>
I expect #schools-list to be visible, but for some reason overflow-x: hidden in #schools-container hides it.
The way you made the two divs (with an absolute position) void the overflow rule!
You need to change the position type (to normal/not absolute) and I suggest using floats, finally, the container div that you want to apply the overflow, needs to have a way to fit it, like placing a div at the end with clear: both (in the case of using floats).
EDIT: I just tried it and you can hide the second div by following the upper suggestion and adding another surrounding div inside with a very large width and change the overflow-x to overflow for the main container div.
Like this:
<div id="schools-container">
<div id="schools-container-inside">
<div id="schools-list"> One </div>
<div id="boards-list"> Two </div>
</div>
</div>
And then the CSS (I commented the original not used CSS and added the new div class at the end):
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
/*overflow-x: hidden;*/
overflow: hidden;
}
#schools-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: purple;
/*
position: absolute;
top: 0;
left: 0;
*/
float: left;
}
#boards-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: green;
/*
position: absolute;
top: 0;
left: 400px;
*/
float: left;
}
#schools-container-inside {
width: 10000px;
overflow: hidden;
}
JsFiddle here: http://jsfiddle.net/MbMAc/
I think you need this
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
overflow-x: hidden;
overflow-y:auto;
height:600px;
}
You need to define height of main div as well.

Resources