Alright, I have no idea what I'm doing. I thought that there would be a library for this, but apparently there isn't.
Problem Explanation
I have a complicated React Application.
There exists
Main Page Element
A content container
A display container
The element I want to scroll to
I am trying to find a solution that will scroll to an element on a page and force all parent scrollbars to scroll to the appropriate location in order to view the element on screen.
Example
<html>
<head />
<body>
<div style="background:red; display: block; height: 1000px; overflow-y: auto">
Root Parent
<div>
<div style="background:green; display: block; height: 1000px;overflow-y: auto">
Another Parent
<div>
<div style="background:blue; display: block; height: 1000px; overflow-y: auto"></div>
<div style="background:purple; display: block; height: 1000px; overflow-y: auto">
<div id="targetElement">Scroll here</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
JS Fiddle Here
https://jsfiddle.net/10f83ush/
Solutions I've tried
I found zen scroll
But in their How to Use Section - 1.4 they explicitly state it isn't supported
https://zengabor.github.io/zenscroll/#howtouse
I found this this thread here
Scroll all nested scrollbars to bring an HTML element into view
And I thought that would work but it doesn't.
If I do element.scrollIntoView that doesn't work either because it's got two sets of scrollable parent/grandparent that both need to scroll to.
Request
How the heck do I get all the parents of the target I want to scroll towards to all scroll towards the correct location to show the element on the page?
I feel like I'm going crazy. It's 2020 and I can't simply scroll to an element that's nested inside other scrollable elements?!
EDIT
To clarify, I'm not trying to do a million scroll bars at a time (Yes this is bad UI/UX), but the solution I'm searching for should support as many as possible. There are multiple solutions I've found where the answer has been solved, but only for one or two scroll bars and then ignored more than two. I would love for guidance or help on how to handle any amount of parent scroll bars when trying to scroll a nested element into view.
Without creating a more complicated solution I opted to use a library called scroll-into-view.
https://github.com/KoryNunn/scroll-into-view
https://www.npmjs.com/package/scroll-into-view
This library is AMAZING - and it does EXACTLY what I wanted which is scrolling elements into view.
Additionally it supports arbitrarily offsetting the scroll location, the ability to filter scrollable areas so that it doesn't change focus from the entire page, and a ton of other amazing features.
This was so good I decided to contribute to the patreon for it!
If you're looking for a solution I would suggest trying this library out!
Related
I am trying to create a "document viewer" of sorts using html and css. I'm wanting the end result to look somewhat of a pdf when viewed in an iframe with no border.
I have a parent div setup with a class of paper. This has some box shadow and other styles attached to it.
<div class="paper">
</div>
Within this I have children divs setup with a class of page. This is where all the content sits for the page.
<div class="page">
</div>
My problem is when the content gets too long for a page and you scroll to the next "page" it all mixes together and looks like junk. I have attached a code pen to further assist in being able to visually see what I am struggling with.
CodePen
CodePen Link Here
You can change your page class in CSS with this:
.page {
height: 100%;
margin-bottom: 15px;
padding: 20px;
display: table;
text-align: center;
}
What is the problem?
If the content in your pages gets too long, it overflows the height end kind of "bleeds" on the next page.
What to do?
You should set a fixed height of 100vh to your paper
Then, tell it not to expand with: overflow: scroll
Use min-height to set the height of your page, instead of height: it will naturally expand the height of the pages instead as you content grows
Finally, just in case, set overflow: hidden to page
I want to place a large image inside a div and let the user scroll through the image using the mouse (click and drag to the desired direction). How can this effect be achieved?
CSS:
#image{
position: relative;
margin: 0 auto;
width: 600px;
height: 400px;
top: 300px;
background: url("http://www.treasurebeachhotel.com/images/property_assets/treasure/page-bg.jpg") no-repeat;
}
HTML:
<div id="image"></div>
EDIT:
I want to implement this myself in order to gain knowledge, 3rd party frameworks are last resort.
<html>
<body>
<div style="width:200;height:200;overflow:scroll;">
<img src="/home/james/Pictures/scone_ontology.png" />
</div>
</body>
</html>
Check out jQuery UI Draggable. The first example sounds like exactly what you are trying to do:
https://jqueryui.com/draggable/
So you just want 600w 400h div, with a "map" inside that you can scroll around and look at with the mouse? You're very close already.
Have a div with the size you want the end-product to take up. Make sure you set its css to overflow:scroll;. Then put your image inside this div. Your image can ofcourse also be the background-image of a div.
And that's it.
A cool trick would be to wrapp all this up in a div that is slightly smaller, with overflow:hidden. Just small enough to hide ugly scrollbars. But that might be bad usability.
I have a set of data being displayed as a tree by the help of jstree plugin and jquery.
The data shows up perfectly in the tree structure. On expanding the last node in the tree the scrollbar appears on the right side of the div block.
Problem:
However if I navigate within the tree with the mouse over the scrollbar, the scrollbar keeps on scrolling down and does not go up.
I am at wits end what could the reason be. I am using a Mozilla Firefox browser.
Please help.
Sample Code below:
css:
.myScrollableBlock {
display: block;
height: 170px;
overflow: auto;
}
.jsp:
<div id="myTreeDiv" class="myScrollableBlock">
</div>
.js:
$('div#myTreeDiv').jstree({
// jsTree plugins
...
...
...
});
How to Solve
You just have to create another div, before the div where you instantiate the jstree, and add the class="myScrollableBlock" at the outer div. Like this:
<div class="myScrollableBlock">
<div id="myTreeDiv"></div>
</div>
Explanation
When you dinamically create the jstree, calling the jquery function
$('div#myTreeDiv').jstree({...});
It overlaps any the static css style specified before (class="myScrollableBlock" in your case).
You can make a quick check this way:
<div style="padding: 20px 20px; overflow: auto; height:170px;">
<div id="myTreeDiv"></div>
</div>
Why CSS is overlapped by JS?
When loading an HTML file, the browser executes the JS scripts after the DOM and the CSS files are built. Overlapping anything that has been done before.
Image source: https://www.sitepoint.com/optimizing-critical-rendering-path/
I have a site that I've been working on the the past couple of weeks. I have a very nice footer on it, problem is, it doesn't stay at the bottom. I've come up with a simple solution.
If the page isn't completely filled (i.e. the content only goes half way down), absolute position the footer to the bottom.
If the page is overflowing (vertically), leave the footer as just another element.
Problem is, I don't know how to check if my content is overfilled. Is there a way to check if the document fills up all the space vertically? The only thing I can think of is to check to see if the vertical scroll-bar is enabled, however, I don't know how to check for that either.
I'm using jQuery, answers with it are fine. Thanks!
EDIT
OK, my question was apparently misunderstood. Sorry guys, I don't need solutions on how to keep my footer at the bottom. I need ways of determining if data overflows on the y-axis. I happened to mention my reason why I needed to know this. Don't make me regret this guys :p
I've used this successfully many times over: http://cssstickyfooter.com. No JavaScript needed at all.
Using jQuery, $(window).height() is how you get the height of the viewport. You can check this value against your content's height:
if($("#content").height() > $(window).height()) {
// absolute position my footer
}
Use the Sticky Footer technique like Matt posted.
The basic idea of it is that you set a static height for your footer. Make your webpage take up the full height of the browser. Push the footer off the screen from the #content div, and then move the footer back onto the page with a negative margin value.
It's hard to answer without seeing your HTML, but if you are using jquery just use outerHeight to get the vertical size of the elements on your page and compare it to window.height
You could apply the css clearfix trick. As stated it is hard with out seeing your code. Even still this could work.
Example:
<html>
<style>
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
</style>
<body>
<div id="content" class="clearfix">
</div>
<div id="footer">
</div>
</body>
</html>
This helps to keep content from overflowing and should keep your footer at the bottom or below your content.
I have three divs with display: inline-block. In every div i have div with display: none when im trying to show hiding div with $('#div-id').show(1000) nearest divs 'jump around'
What should i change? I do like to see div under div just draw and the left or right div doesn't change his place.
For example two divs with my problem there (hide div shows up onchange in the textbox)
http://jsfiddle.net/WZCJu/13/
I added this CSS:
#amount-div, #specific-div {
width: 300px;
vertical-align: top
}
Version without the width, you may like it better:
http://jsfiddle.net/WZCJu/15/
Try using css's visibility property instead since it retains the element's position in the flow.
Docs: http://www.w3schools.com/css/pr_class_visibility.asp
Example:
<div id="herp" style="width: 100px; height: 40px; visibility: hidden;">plarp</div>
<div id="derp" style="width: 100px; height: 40px; visibility: visible;">slarp</div>
If you change the divs to use float: left; with a specified width you can avoid the "jump around".
See my updated example at: http://jsfiddle.net/WZCJu/12/
I changed the following:
<div id="amount-div" style="display:inline-block;">
...
<div id="specific-div" style="display:inline-block;">
To use floats with a specified width.
<div id="amount-div" style="float:left;width:220px;">
...
<div id="specific-div" style="float:left;width:220px;">
I also changed the <br> tag which preceeds the submit button so that it will clear the floated divs like so (though, there are better ways of handling that in my opinion):
<br style="clear:both">
display none removes the element completely from the document. there wont be any space reserved for it. so when u bring it back(show) it ll rearrange the nearby divs. so try using visibility:hidden which will retain the space but keep the div hidden..
Changing an HTML element from display: none to display: block or some other value will always cause it to change the flow of other elements around it in the tree. To prevent the DIVs from jumping around, you have a few options. Here are a couple simple ones:
First, you could "pad" the DIV in another DIV with a fixed size. For example:
<div style="width: 100%; height: 2em;">
<div id="js-amount" style="display: none">
<p>You will achieve this goal by:</p>
<p id="achieved-date"> <p>
<p id="weekly-limit-amount">Your weekly limit will be decreased by $100</p>
</div>
</div>
Secondly, you could use absolute positioning to remove your DIV from the flow of the document:
<div id="js-amount" style="display: none; position: absolute; top: 200px; left: 50px;">
<p>You will achieve this goal by:</p>
<p id="achieved-date"> <p>
<p id="weekly-limit-amount">Your weekly limit will be decreased by $100</p>
</div>
You must set a fixed size for your divs, so when the new one appears, it's constrained with the given side. I updated your JSFiddle : http://jsfiddle.net/WZCJu/16/
Have a look at how I constrain the size for your divs in the CSS. To improve layout, I took the liberty to add some styling to the submit button, so the HTML is a little bit modified too.
If you have any trouble understanding my solution, ask some questions.
When using display: none, the element does not render at all so it doesn't use any space on the rendered web page. I think you might want to use visibility:hidden to hide your element but still make the space usage calculation.
EDIT: It appears jQuery method works only on the display style so my answer is not applicable and indeed a fixed offset is necessary to avoid side effects in the page flow.