scrollIntoView() is not working: does not taking in account fixed element - javascript

I'm trying to use scrollIntoView() in my application, but because I have a top fixed bar, when I use the scrollIntoView(), the elements will be scroll to the fixed bar back.
This means that when I try to put some element visible to the user, by scrolling the element to a visible area, it will be scrolled, but to another invisible ate that is were this fixed bar is.
Follows an example of what I'm trying to do:
let element = document.getElementsByClassName('second-element')[0];
element.scrollIntoView();
.fixed-element{
height: 30px;
width: 100%;
background-color:black;
position:fixed;
}
.parent-element {
width: 100%;
height: 40000px;
background-color:blue;
}
.element {
width: 100%;
height:100px;
background-color: yellow;
margin-top:10px;
}
.second-element{
width: 100%;
background-color: red;
height:200px;
}
<div class="fixed-element"></div>
<div class='parent-element'>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='second-element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
<div class='element'></div>
</div>
There is any way that I could use this function in a way that the scroll elements not became invisible because of the fixed bar?
I would like a vanilla JavaScript solution. Also, and only if it is possible, a solution that doesn't need to know the existent of any fixed elements.

You can make the window scrollTo x position 0 and y position the element's offsetTop subtracted by the fixed element's offsetHeight.
JSFiddle with your code: http://jsfiddle.net/3sa2L14k/
.header{
position: fixed;
background-color: green;
width: 100%;
top: 0;
left: 0;
right: 0;
}
html, body{
height: 1000px;
}
#toBeScrolledTo{
position: relative;
top: 500px;
}
<div class="header">
Header
</div>
<div id="toBeScrolledTo">
Text Text Text
</div>
<script>
window.scrollTo(0, document.getElementById('toBeScrolledTo').offsetTop - document.getElementsByClassName('header')[0].offsetHeight);
</script>

Your question is answered in this link.
var node = 'select your element';
var yourHeight = 'height of your fixed header';
// scroll to your element
node.scrollIntoView(true);
// now account for fixed header
var scrolledY = window.scrollY;
if(scrolledY){
window.scroll(0, scrolledY - yourHeight);
}
Also you can use this way:
let item = // what we want to scroll to
let wrapper = // the wrapper we will scroll inside
let count = item.offsetTop - wrapper.scrollTop - xx // xx = any extra distance from top ex. 60
wrapper.scrollBy({top: count, left: 0, behavior: 'smooth'})
Source: https://github.com/iamdustan/smoothscroll/issues/47

A great simple solution (inspired by Sanyam Jain's comment in this link) is to use {block: 'center'} to vertically center the selection like this:
scrollIntoView({block: 'center'})
Edit - I sadly found on MDN page that this features is 'experimental - should not be used in production'. Also, IE doesn't support it (if that's a need).

Try scroll padding. It is not a JavaScript solution (it is a CSS property) but it can be helpful with your problem.
MDN
CSS Tricks

This is 2021, so you could solve this by just using scroll-margin-top. It exists for this express purpose!

Related

Inverse direction of jQuery UI resizable

I have a floating sidebar which is located on the right of the page which I want to be able to resize using a handle on the left of the container.
At the moment, when I drag the sidebar using the handle, it makes the sidebar wider when dragging right, and smaller when dragging left - I wan't it to do the inverse of this. i.e., dragging to the left increases the size of the sidebar etc..
I would prefer to not change the html structure and hopefully have a simple line of javascript to fix the problem - please help!
Here is a fiddle: https://jsfiddle.net/c01gat3/us8vktjq/
html
<div id="sidebar">
<div id="drag">
</div>
</div>
css
#sidebar{
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100% !important;
background-color: blue;
}
#drag{
position: absolute;
left: -10px;
width: 10px;
height: 100%;
background-color:black;
cursor:ew-resize;
}
Javascript
$('#sidebar').resizable({
minWidth: 100,
handles: { "w" : $("#drag") }
});
You're missing the associated CSS file.
Add the following reference to your HTML page:
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
Adjust your HTML code to include the needed classes:
<div id="sidebar">
<div id="drag" class="ui-resizable-handle ui-resizable-w">
</div>
</div>
Working fiddle here: https://jsfiddle.net/us8vktjq/2/
Read more here: http://api.jqueryui.com/resizable/#option-handles

How to position a div above another div?

My code is:
HTML:
<section>
<div id="banner">
<div class="container">
<p class="para">hello world</p>
</div>
<div class="container banner-bottom">
<div class="card card-primary text-center z-depth-2 contact-main-text">
<div class="card-block">
<p class="white-text">Please fill out the form below and ESC
staff will be in contact with you shortly.</p>
</div>
</div>
</div>
</div>
</section>
CSS:
.para{
color:white;
background: red;
padding:70px;
text-align:center;}
.white-text{
background:green;
padding:20px;}
Output is: Bootply
And i want:
Could anyone help me with that?
You can set negative top margin to overlay the second div, see the live example:
<div class="container banner-bottom" style="margin-top:-5%;padding:2%">
http://www.bootply.com/MorC45NB4V
PS: I have used inline css just to show, avoid inline css.
My solution uses jQuery and some calculations. My calculation works even if you move the elements around the document. I also used CSS for the margins you wanted.
jQuery
//location of bottom of the red container
var bottomOfContainer = $('#onTopOfMe').offset().top + $('#onTopOfMe').height();
//gets the bottom 4th of the red container
var placement = bottomOfContainer - ($('#onTopOfMe').height() / 4);
//setter of top for green container
$('#placeMe').offset({"top": placement});
CSS
p.white-text{
margin-left:5%;
margin-right:5%;
}
Output
bootply
1) In case you want your lower banner to have a full width:
You could add position: relative; to the lower banner and position it adding a bottom value and use margin to create the same visual effect asked in the question.
.banner-bottom {
position: relative;
bottom: 45px;
margin: 0 40px;
}
2) In case you don't need to have a banner with full width and just center it, then no need to use margins. Remember to set one parent as position: relative;:
#banner { position:relative;}
.banner-bottom {
position: absolute;
top:75%;
right:0;
bottom:auto;
left:0;
}
CODEPEN
http://codepen.io/alexincarnati/pen/PWOPjY
Here's my solution for this.
Basically just make the position of the card block "relative", position the "top" position accordingly, then set the margin to "auto" to center it.
.card-block {
position: relative;
top: -50px;
margin: auto;
width: 80%;
}
A bit of position could help you, here's a rough version that will hopefully get you thinking what you need to do:
#banner { position:relative;}
.banner-bottom { position: absolute; top:75%;right:0;bottom:auto;left:0; }
Heres a forked bootply: http://www.bootply.com/Imuh4wUj50

Using Text With The Trianglify Javascript Library

So I've been using the Trianglify library and I've been loving it. My only problem is the way it handles text: it pushes it all to the top, whereas I want the randomly generated background to act as the background, with the text on it. Here's my code so far:
<script>
var pattern = Trianglify({
height: window.innerHeight,
width: window.innerWidth,
cell_size: 40});
document.body.appendChild(pattern.canvas())
</script>
and
<div class="container-fluid" id="welcome">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1> Welcome to the website </h1>
</div>
</div>
</div>
Please help! Thanks so much for your time.
I just came across this question because I have the same issue. Here's what I did.
HTML
<canvas id="container1"></canvas>
<script>
var pattern = Trianglify({cell_size: 25, x_colors: 'Blues'});
pattern.canvas(document.getElementById('container1'));
</script>
<div class="screen-container trianglify-container">
<div class="container">
<div class="row">
<h3>This is where my text goes</h3>
</div>
</div>
</div>
CSS
.trianglify-container {
background-color: transparent;
color:#fff;
text-align: center;
padding-top: 20vh;
}
canvas#container1 {
position: absolute;
width: 100vw;
height: 100vh;
}
Explanation
I am using Bootstrap, hence the container and row divs in the HTML.
Setting the canvas#container1 to an absolute position fixes it and everything that follows in the HTML should come over it. Setting width to 100vw and height to 100vh ensures it takes up the whole screen.
Setting the trianglify-container position to relative ensures it shows up relative to any fixed or absolute objects above it, in this case the canvas. Using padding let's you move where you want the text.
If I wanted everything else on the page always to have the same trianglify background, I could do:
canvas#container1 {
position: absolute;
width: 100vw;
height: 100vh;
}

Make Div fixed bottom & scrollable

I want to have a long page, with a fixed top 100px div, and a fixed 50px bottom div. However, I want the bottom div to scroll as you scroll down the page.
Its hard to explain, but the best example of this is on the front page of PayPal.com
On the first page load, the bottom div looks like it is fixed, and as you adjust the height of the browser window, that div stays at the bottom. Yet as you scroll down the page it is not fixed.
Can anyone explain how they have done this? I am trying to re-create something similar, but cant see how they have managed it.
As far as I can see they have this html...
<div id="fixed-top">
<header class="table-row">
// header content
</header>
<div class="table-row table-row-two">
// Video content
</div>
<div class="table-row">
//bottom content
</div>
</div>
And this CSS...
#fixed-top {
height: 100%;
width: 100%;
display: table;
position: relative;
top: 0;
left: 0;
z-index: 1;
}
.table-row {
display: table-row;
}
But that alone doesn't do it. I also can't see any js thats getting window height and applying it to the main fixed div.
Help! :)
EDIT:
Have just found a way to do it with javascript, controlling the height of the middle row using the window height, minus the 150px for the header and third row.
jQuery(document).ready(function(){
$('div.table-row-two').css({'height':(($(window).height())-150)+'px'});
$(window).resize(function(){
$('div.table-row-two').css({'height':(($(window).height())-150)+'px'});
});
});
But saying that, Zwords CSS only method seems like a winner.
From what I understand, you are looking for something like a sticky footer. So basically if the content is not enough, the footer should go sit at the bottom like its fixed, but if content comes in, it should scroll down like other content.
Try this - http://css-tricks.com/snippets/css/sticky-footer/
First off, you'll need to set the height of the body and html tag, otherwise the table won't take the full screen. Then I altered your code, made it a bit easier.
HTML:
<div id="fixed-top">
<header>
// header content
</header>
<div>
// Video content
</div>
<div>
//bottom content
</div>
</div>
CSS:
html, body {
margin: 0;
padding: 0;
height: 100%;
min-height: 100%;
}
#fixed-top {
display: table;
width: 100%;
height: 100%;
}
#fixed-top > * { /* makes all the direct children of #fixed-top a table row*/
display: table-row;
background: lightblue;
}
#fixed-top > *:nth-child(1) {
background: lightgreen;
height: 40px;
}
#fixed-top > *:nth-child(3) {
background: lightgreen;
height: 25%;
}
You can either set the height to a fix height (in px) or percentages. If you only give two of the three rows a height, the third one will automaticly fill up the rest space.
Also, check this demo.
Check this fiddle / Fullscreen
Using display:table;,display:table-row;,min-height to adjust to screen
HTML
<div class="wrapper">
<div class="row">menu</div>
<div class="row">content</div>
<div class="row">footer</div>
</div>
<div class="wrapper">
<div class="row">content1</div>
<div class="row">content2</div>
<div class="row">content3</div>
</div>
CSS
html,body,.wrapper{
width:100%;
height:100%;
margin:0px auto;
padding:0px;
}
.wrapper{
display:table;
border:1px solid black;
}
.wrapper .row{
display:table-row;
background-color:rgb(220,220,220);
}
.wrapper .row:nth-of-type(1){
min-height:15px;
}
.wrapper .row:nth-of-type(2){
height:100%;
background-color:white;
}
.wrapper .row:nth-of-type(3){
min-height:15px
}
You can do this easily with jQuery using $(window).height() and subtracting your footer/header's heights. See Fiddle for an example.

How to set a position of an element 5px below a fixed position element

Ex: the 1st Div:
<div style='position: fixed; width=100%'> ....</div>
Now i want to put another Div 5px right below the previous Div. So i did
<div style='padding-top:5px; width=100%'> ....</div>
But it didn't work, seem padding-top compare itself to the top of window but not to its previous Div. If i remove the position: fixed; in the 1st div then it will be fine, but i don't want that.
I want the 1st Div got position fixed & the 2nd Div's position is 5px right below the 1st one. So how to do that?
position: fixed removes the element from the regular flow. You can't use flow positioning anymore.
There are likely proper ways to do what you want, but I don't know what you want because you told us about Y, not X: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
I think I understand what you want. If you always know how high the header is you can just add an offset, padding and margin should both work.
<div id="header" style="position: fixed; top: 0; width: 100%; height: 20px;">
<div id="content" style="margin-top: 20px;">Content goes here</div>
If the header can change height adjust your CSS so that the header and content change their height and content respectively.
<div id="container" class="adjustheaderheight">
<div id="header">
<div id="content">Content goes here</div>
</div>
#header { position: fixed; top: 0; width: 100%; height: 20px; }
#content { margin-top: 20px; }
#container.adjustheaderheight #header {
height: 40px;
}
#container.adjustheaderheight #content {
margin-top: 40px;
}
If your header changes height dynamically you'll need to change the content offset dynamically although I would strongly advise you not to have a dynamic header.
Have you tried margin-top instead?
margin-top: 5px
You might wanna include both these divisions within another division and make this new outer division position fixed. Like this --->
<div style='position: fixed; width=100%'>
<div style='width=100%'> ....</div>
<div style='padding-top:5px; width=100%'> ....</div>
</div>
put the two divs in a wrapper posioned fixed. Also you have invalid css syntax width=100% must be width:100%.
<div style="position: fixed;">
<div style=' width:100%'> ....</div>
<div style='margin-top:5px; width:100%'> ....</div>
</div>
however, this makes the 2 divs fixed... and this might not be what you want. You could do the following:
<div style='position: fixed; width:100%'> ....</div>
<div style='position:absolute; width:300px;height:200px;top:300px;left:300px'> ....</div>
css values are just for example...
UPDATE:
is this what you want?
http://jsfiddle.net/kasperfish/K8N4f/1/
<div id="fixed">fixed</div>
<div id="widget" >content <br>hjgjhgjhgjhgh</div>
#fixed{
width:100%;
position:fixed;
background:yellow;
height:50px;
z-index:2;
}
#widget{
background:blue;
position: absolute;
top:55px;
margin-top:15px;
width:100%
}
If you have tried Margin and it doesn't work feel free to use padding as long as you don't have a background color or image within the div then you won't be able to tell the difference between the two ways of doing this.

Categories