Is there any way to make a div son, float while rolling the scroll of the father div?

Asked

Viewed 1,279 times

4

I have a div primary, and within this, another div(secondary).

I’m trying to position the div secondary in div so that it makes a floating DIV (popup style) that overlaps with other elements.

But for this particular case, I want to override the content of div and when rolling the Scroll to div child must accompany.

Follow the code below.

#Pai {
    position: relative;
    width: 400px;
	height: 200px;
	border: 3px solid blue;
	text-align: center;
	overflow: auto;
}

#Filho {
	width: 100px;
	height: 100px;
	margin-left: -50px;
	/* metade da largura */
	margin-top: -50px;
	/* metade da altura */
	position: absolute;
	top: 50% ;
	left: 50% ;
	background: tomato;
	z-index: 1; // sobrepor
	-moz-opacity: 0.8;
	opacity: .80;
	filter: alpha(opacity = 80);
}
<div id='Pai'>
  
	<p>Elemento A</p>
    <p>Elemento B</p>
    <p>Elemento C</p>
    <p>Elemento D</p>
    <p>Elemento E</p>
    <p>Elemento F</p>
    <p>Elemento G</p>
    <p>Elemento H</p>
    <p>Elemento I</p>
    <p>Elemento J</p>

    <div id='Filho'></div>

</div>

It would be possible to develop a Script to achieve this, without having to change all the syntax of CSS?

For example

var scrolldellay = document.getElementById("Pai");

   scrolldellay.scrollBy = function() {
                  ...
    // Coloque a rotina implementada
                  ...
 }
  • Modifying the position:absolute; for position:fixed; not fit for your case?

3 answers

2

As his friend @Cʜᴜɴ commented, just changing from position:absolute; for position:fixed; to div (red) center keeps fixed, and changed position(top,left) p/ keep it in the center.

#Pai {
    position: relative;
    width: 400px;
	height: 200px;
	border: 3px solid blue;
	text-align: center;
	overflow: auto;
}

#Filho {
	width: 100px;
	height: 100px;
	margin-left: -50px;
	/* metade da largura */
	margin-top: -50px;
	/* metade da altura */
	position: fixed; /* alterei aqui */
	top: 30% ; /* alterei aqui */
	left: 200px ; /* alterei aqui */
	background: tomato;
	z-index: 1; // sobrepor
	-moz-opacity: 0.8;
	opacity: .80;
	filter: alpha(opacity = 80);
}
<div id='Pai'>
  
	<p>Elemento A</p>
    <p>Elemento B</p>
    <p>Elemento C</p>
    <p>Elemento D</p>
    <p>Elemento E</p>
    <p>Elemento F</p>
    <p>Elemento G</p>
    <p>Elemento H</p>
    <p>Elemento I</p>
    <p>Elemento J</p>

    <div id='Filho'></div>

</div>

A script without needing to change the css, using jquery

$("#Pai").scroll(function() {
  console.log($("#Pai").scrollTop());
  $("#Filho").css("top", $("#Pai").scrollTop() + 100);
});

Using the same example, now the child div is repositioned according to the value of . scrollTop() of the parent div, which returns the current vertical position of the scroll bar, put +100 simply p/ keep centered, you can change the value quietly p/ see how it behaves, note that when scrollar the body does not affect the position of the child div.

Demo - jquery

  • @Diegohenrique, 3 lines in css only, commented in code =)

  • A fixed element - fixed - is positioned relative to the "viewport", it means that it will always be in the same place even if there is scrolling on the page. A detail here is when an element receives position:fixed, it is free/independent not only of its relative, but of the document as a whole. position:fixed is always fixed to the window and not to the element in which it is inserted. It seems to me that we have to set the values of the properties top and left in "pixel" and use the fixed element - fixed.

  • The element position:fixed does not fit very well to my need, the position which would best suit position:absolute. But your answer is already valid. =)

  • Really, if the parent element of the parent div possesses scroll the central div(son) will accompany the scroll, p/this case I think it would be interesting to put a function $("#Father"). scroll(Function() {..}); that when scrollar the father div, move the son div, with position:Bsolute; obviously, if you find it necessary I can implement in the answer.

  • @Diegohenrique, give a look here: https://jsfiddle.net/mathiasfcx/sac5sL3u/ I took the same example, I put position:abosulte in div son and a function in div father, that when scrolling div father to div son is repositioned according to the value of . scrollTop(); which returns the current vertical position of the scroll bar, put +100 simply to centered, you can change the value quietly p/ see how it behaves,put a body with scroll p/ show that the scroll will not affect the child div, any doubt just call.

1

you can use the event scroll as mentioned, but the top value should take into account the initial 50.

Below follows an example.

Modernizr.addTest('csscalc', function() {
    var prop = 'width:';
    var value = 'calc(10px);';
    var el = document.createElement('div');
    el.style.cssText = prop + Modernizr._prefixes.join(value + prop);
    return !!el.style.length;
});

Modernizr.addTest('mozcsscalc', function() {
    var prop = 'width:';
    var value = '-moz-calc(10px);';
    var el = document.createElement('div');
    el.style.cssText = prop + Modernizr._prefixes.join(value + prop);
    return !!el.style.length;
});


var pai = document.getElementById("Pai");
var filho = document.getElementById("Filho");
pai.addEventListener("scroll", function (e) {
  if (Modernizr.csscalc) {
    filho.style.top = "calc(50% + " + pai.scrollTop + "px)"
  } else if (Modernizr.mozcsscalc) {
    filho.style.top = "-moz-calc(50% + " + pai.scrollTop + "px)"
  }
});
#Pai {
  position: relative;
  width: 400px;
  height: 200px;
  border: 3px solid blue;
  text-align: center;
  overflow: auto;
}

#Filho {
  width: 100px;
  height: 100px;
  transform: translate(-50%, -50%);
  position: absolute;
  top: 50%;
  left: 50%;
  background: tomato;
  z-index: 1; // sobrepor
  -moz-opacity: 0.8;
  opacity: .80;
  filter: alpha(opacity = 80);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
<div id='Pai'>  
<p>Elemento A</p>
  <p>Elemento B</p>
  <p>Elemento C</p>
  <p>Elemento D</p>
  <p>Elemento E</p>
  <p>Elemento F</p>
  <p>Elemento G</p>
  <p>Elemento H</p>
  <p>Elemento I</p>
  <p>Elemento J</p>
  <div id='Filho'></div>
</div>

P.S.: you do not need a negative margin to adjust the position of the div, for such you can use a Translate of -50%.

  • I’m using a Firefox 11 on a Dlinux platform, and it didn’t roll. Which browser did you develop?

  • I’m using the Opera

  • 1

    @Diegohenrique what is the need to use a Browser that has been released for 5 years and no longer has support from Mozilla?

  • 1

    @Diegohenrique added a fallback to Mozilla 11, but I would advise you to update your browser, or at least warn that it is using a prehistoric browser when asking the question.

  • Well, Linux is robust, but when there is a need to install its packages, there is often some conflict between libraries. Then the rush begins to solve, because in many cases we have to compile everything in the nail. But I have Slax with Firefox 38, and I know that Firefox is already in its 52+ version. But for each new upgrade requires most of the time a new machine. Unfortunately it is not only me, but there are other users without new PC, even more in crisis. And thinking like this, I like programming everything portable, semantic widely compatible with more than 40 browsers

0


With the answers I got from Mathias and followed by Tobias Mesquita, before its new edition.

I arrived at two similar alternative, I believe it is Cross-Browser.

1.ª.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>

<style type="text/css">

body {
        height: 999px;
}

#Pai {
        position: relative;
        width: 200px;
        height: 200px;
        border: 3px solid blue;
       text-align: center;
       overflow: auto;
}

#Filho {
        width: 100px;
        height: 100px;
        margin-left: -50px;
        /* metade da largura */
        margin-top: -50px;
        /* metade da altura */
        position: absolute;
        top: 50% ;
        left: 50% ;
        background: tomato;
        z-index: 1;
        opacity: .80;
}

</style>

</head>
<body>
<center>

<div id='Pai' onscroll = "rolamento()">

        <p>Elemento A</p>
        <p>Elemento B</p>
        <p>Elemento C</p>
        <p>Elemento D</p>
        <p>Elemento E</p>
        <p>Elemento F</p>
        <p>Elemento G</p>
        <p>Elemento H</p>
        <p>Elemento I</p>
        <p>Elemento J</p>

     <div id='Filho'></div>

</div>

</center>
<script type="text/javascript">

var A = document.getElementById('Pai'); 
var B = document.getElementById('Filho'); 

var rolamento = function() {    
    var centralizado = A.scrollTop + 100; 
    B.style.top = centralizado; 
}

A.onscroll = rolamento;

</script>
</body>
</html>

Follows Explanation

var A = document.getElementById('Pai'); // Div(primária)

var B = document.getElementById('Filho'); // Div(secundária)

var rolamento = function() {

        var centralizado = A.scrollTop + 100; // Aqui definimos o valor 100 para reposicionar a Div(secundária) conforme o valor scrollTop() da Div(primária) 
        B.style.top = centralizado; // Agora vamos automatizar a Div(secundária), para retomar sempre a mesma posição inicial

}

A.onscroll = rolamento; // Escuta o evento da barra de rolagem lateral e dispara a função

NOTE - "This 1st Amendment worked perfectly on the local computer, but did not have the same breakdown when I tried to add as sample on http://jsbin.com/ and http://jsfiddle.net/. However the Script itself works, being below the </body>. Whatever it may be, the cause, is of a nature unknown to me."


2.ª.

var A = document.getElementById('Pai');  // Div(primária)
var B = document.getElementById('Filho'); // Div(secundária)
var P = B.scrollHeight / 2;
A.onscroll = new Function("if(B.style.top = A.scrollTop + P + 'px') return true");
body {
    height: 999px;
}

#Pai {
   position: relative;
   width: 200px;
   height: 200px;
   border: 3px solid blue;
   text-align: center;
   overflow: auto;
}

#Filho {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 25%;
    left: 25%;
    margin: 0 auto;
    background: tomato;
}
<center>

<div id='Pai'>

    <p>Elemento A</p>
    <p>Elemento B</p>
    <p>Elemento C</p>
    <p>Elemento D</p>
    <p>Elemento E</p>
    <p>Elemento F</p>
    <p>Elemento G</p>
    <p>Elemento H</p>
    <p>Elemento I</p>
    <p>Elemento J</p>

 <div id='Filho'></div>

</div>

</center>

Jsbin - External sample

Explaining

var P = B.scrollHeight / 2; 

I’m splitting up the div(secondary), by its actual size, i.e.:

Tam.: 100 2 = 50

We save this value(50) in the variable P and launch on condition if.

A.onscroll = new Function("
   if(B.style.top = A.scrollTop + P) return true
");

Soon the scroll that it is linked to the element div(primary), is slided

Each "1px" will be called to new Function() for the execution

Which followed the condition if, takes action for your position

And in the blink of an eye returns true(repositioning carried out).

Ready!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.