Is there a way to make a child div float by scrolling the scroll of the parent div?

4

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

I'm trying to position the div pendent% in the primary div so that it becomes a floating DIV (popup style) that overlaps the other elements.

But for this particular case, I want to override the contents of the div main and when rolling 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>

Would you like to develop a Script to achieve this effect, without having to change every syntax of CSS ?

For example

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

   scrolldellay.scrollBy = function() {
                  ...
    // Coloque a rotina implementada
                  ...
 }
    
asked by anonymous 04.04.2017 / 05:57

3 answers

2

As friend @ Cʜᴜɴ commented, only changing from position:absolute; to position:fixed; to div central (red) stays fixed, and changed the position (top, left) to keep it in the center. p>

#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 .scrollTop () value of the parent div, which returns the current vertical position of the scroll bar, I put +100 simply to keep it centered, you can change the value quietly to see how it behaves, note that scrolling the body does not affect the position of the child div.

Demo - jquery

    
04.04.2017 / 13:00
1

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

Below is 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>

Q: You do not need a negative margin to adjust the position of the div, for this you can use a translate of -50%.

    
04.04.2017 / 14:36
0

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

I came up with two similar alternatives, I believe it's Cross-Browser.

1st_Alternative

<!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>

Follow 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_Alternative worked perfectly on the local computer, but it did not have the same mismatch when I tried to add as a sample in link and link . However the Script itself works, being below </body> . Anything that comes to be the cause, is of a nature unknown to me. "

2nd_Alternative

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 am dividing the div (secondary) by its Actual Size, that is:

Size: 100 ÷ 2 = 50

We saved this value (50) in the P variable and launched it in the if condition.

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

Then the scroll that is attached to the element div (primary), is slid

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

That followed by the condition if , it takes action by its position

And in the blink of an eye, returns true (repositioning done).

Ready!

    
04.04.2017 / 20:29