How to access position of an element relative to its parent element - javascript

I want to get the position of an element relative to its parent element. So for this i am using jquery position function I created a JsFiddle.
In this fiddle i am accessing the top & left position of #child element. It should return top : 0 and left : 0 because it is the children of #p element and its position is relative but it is returning top : 223px and left : 1px. Can anyone please help me ?

here is the tweak
The problem was you did not specify the parent's position as relative. So the child position was calculated with respect to body
<style type="text/css">
#gp {
width: 500px;
height: 200px;
margin: 0;
border: 1px solid black;
background-color:gray;
overflow:hidden;
}
#p {
width: 600px;
height: auto;
float: left;
position: relative;
}
#child{
position: relative;
}
</style>
<div id="gp">
<div id="p">
<div id="child">
</div>
</div>
</div>
jQuery(document).ready(function(){
alert($("#child").position().top + " " + $("#child").position().left);
});

Perhaps something like this :
function relative_pos(node) {
var parentOf = $(node).parent().offset();
var child = $(node).offset();
return {top: child.top - parentOf.top, left: child.left - parentOf.left};
}
console.log(relative_pos("#child"));
Try !!!

Related

position fixed at a given height

I have been trying to put an element to fixed position within a given scroll height with Javascript. Outside of this height range, the position should be back to relative.
Here is what I have done so far. The position:fixed is inside the about-option class. When it gets to 4680, the class is added.
How do I make it have a height end-point of 5800 i.e 4680 - 5800, and also remove the class outside this height range?
window.onscroll = function () {
myFunction();
};
function myFunction() {
if (
document.documentElement.scrollTop > 4680 ||
document.body.scrollTop > 4680
) {
document.getElementById("about-txt").classList.add("about-option");
} else {
document.getElementById("about-text").className = "";
}
}
css
.about-option {
position: fixed;
top: 20%;
width: 40%;
right: 7%;
I guess you are trying to do what position sticky does: once the element hits the window's top boundery it starts sticking and if you scroll to the inverse way, it goes back to move together with content. Like here:
https://codepen.io/elad2412/pen/QYLEdK
<main class="main-container">
<header class="main-header">HEADER</header>
<div class="main-content">MAIN CONTENT</div>
<footer class="main-footer">FOOTER</footer>
</main>
body{color:#fff; font-family:arial; font-weight:bold; font-size:40px; }
.main-container{ max-width:600px; margin:0 auto; border:solid 10px green; padding:10px; margin-top:40px;}
.main-container *{padding:10px;background:#aaa; border:dashed 5px #000;}
.main-container * + *{margin-top:20px;}
.main-header{
height:50px; background:#aaa; border-color:red;
}
.main-content{
min-height:1000px;
}
.main-header{position:-webkit-sticky; position:sticky; top:0;}
The trick part is to remember to add a container outside the sticky element, otherwise, it will not work.
I hope it helps!

why is child element's width changing when parent's width changes?

I am trying to create a tooltip element that has a min width of 50px and a max width of 200px. I place the tooltip element inside another element so that I can easily control when the tooltip appears or disappears when there is a hover event on the parent.
The problem that I have is that the tooltip element's width appears to be controlled by the parent's width even though I specified that the child(tooltip) has an absolute position.
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
position: relative;
transition: width 2s;
}
#tooltip {
position: absolute;
top: calc( 100% + 5px );
left: 5px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>
I would like the tooltip (yellow div) to keep it's size at 200px in this example, but we can see that when the parent changes width, the tooltip width also changes. Why?
Is there a way to fix this problem?
Clarification: In this example: https://codepen.io/anon/pen/ePPWER we see that the tooltip text looks nice on one line. I don't want the tooltip's div to change its width when the parent changes width, because it forces the tooltip text to wrap onto 2 lines which is undesirable.
If we check the specification related to the width of absolutely positioned element we can read this:
'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
So in your case the width of your element is shrink to fit:
Calculation of the shrink-to-fit width is similar to calculating the
width of a table cell using the automatic table layout algorithm.
Roughly: calculate the preferred width by formatting the content
without breaking lines other than where explicit line breaks occur,
and also calculate the preferred minimum width, e.g., by trying all
possible line breaks. CSS 2.1 does not define the exact algorithm.
Thirdly, calculate the available width: this is found by solving for
'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width,
available width), preferred width).
To make it easy, and without considering the min/max-width, the width of your element will try to fit the content without exceding the width of its parent container (containing block). By adding min/max-width you simply add more constraint.
One idea of fix it to remove positon:relative from the parent element so that it's no more the containing block of the position:absolute element (it will be the initial containing block which is wide enough to avoid the available width constraint).
Then use margin instead of top/left to control the position:
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
transition: width 2s;
}
#tooltip {
position: absolute;
margin-top: 30px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>
ID Tooltip is being used under Parent. When parent's width changes, it also suggest that tooltip's total width is changed. Since you have used mix-width and max-width it will expand till it reaches max-width. If you want it to be fixed then simple use width.
It is because the .parent has a position: relative. This will keep all children (position: absolute included) as confined by the parent div.
Not sure if this will work for you because it is pulling the tooltip out of the parent and making it's own with span wrapping the text. Alternatively, you'll need to change the parent from being relative otherwise it'll continually affect the child.
let p = document.getElementById('parent');
let b = true;
setInterval(() => {
b = !b;
let w = 10;
if (b) {
w = 300;
}
p.style.width = `${w}px`
}, 5000);
#parent {
background-color: cyan;
width: 100px;
height: 25px;
transition: width 2s;
position: relative;
}
#root {
position: relative;
}
#tooltip {
width: 100%;
}
#tooltip span {
position: absolute;
top: calc( 100% + 5px);
left: 5px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="root">
<div id="parent"></div>
<div id="tooltip">
<span>My long tooltip text that wraps to multiple lines as needed.</span>
</div>
</div>

How to automatically push scroll-bar when new item was added

Please check out this fiddle. If you add items to the #scroll div, the scroll-bar is fixed - it just stays at the "beginning". What I want to achieve is to move scroll-bar automatically when a new item is being appended to the parent. Is it possible to do this via magic of CSS? :)) Or only JS gonna solve it?
Code:
HTML
<div id="scroll">
<div class="addElement">FIRST</div>
<div class="addElement"></div>
<div class="addElement">LAST</div>
</div>
<button id="add">ADD NEW ELEMENT</button>
CSS
#scroll {
overflow: auto;
overflow-y: hidden;
width: 200px;
height: 150px;
background: red;
position: relative;
display: flex;
align-items: center;
}
.addElement {
margin: 5px;
height: 60px;
width: 55px;
background: green;
flex: 0 0 auto;
}
JS
var scroll = $('#scroll');
var addButton = $('#add');
var item = 1;
addButton.click(function() {
scroll.append(`<div class="addElement">ITEM ${item}</div>`);
item++;
});
Thank you for any suggestion!
I've updated your fiddle to demonstrate a jQuery method of doing this:
https://jsfiddle.net/93gz3u1L/11/
I just added the following using scrollLeft (You can remove the animation if needed):
addButton.click(function() {
scroll.append(`<div class="addElement">ITEM ${item}</div>`);
item++;
scroll.animate({
scrollLeft: scroll.get()[0].scrollWidth
});
});
You can use the css Direction property, setted to rtf! (right to left)
#scroll {
...
direction: rtl;
}
but you will need to prepend the elem instead of append it to the parent.
https://jsfiddle.net/k6Lhv3u6/1/

How to increase width of body with respect to adding elements from database?

I want to increase the width of body of html page with respect to multiple div(having images) retrieve from database.Here is code:
HTML
<div class = "mainDiv">
<div id = "filer" class = "filterPanel">
</div>
<div id="imgPanel" class="imgPanelDiv">
<ul id ="imgPanelUi">
<?php require_once './getData.php';?>
</ul>HTML
</div>
<div>
CSS
.mainDiv{
position: relative;
}
.filterPanel{
width: 20%;
height: 600px;
padding: 40px 0 10px 0;
position: relative;
}
.imgPanelDiv{
width:80%;
position: absolute;
top : 0;
right: 0;
}
I also set <div class="imagePanelDiv" style = "float : left"> but its look strange.
Note
With the above code the body having width until filterDiv(set 600px).After this the body is not available and all the other images are out of bound. I want that body width is increase so that all images( in "imgPanel" class) are display on the body.
Need help?
try this:
min-width: 600px;
width: auto
remove the position:absolute; in you imgPanelDiv

CSS Relative Position/Normal Position Question

According to w3schools, the relative position value is defined as follows.
relative - The element is positioned relative to its normal position, so "left:20" adds 20 pixels to the element's LEFT position.
I know that I can get the DOM object of whatever I positioned relatively and using that, I can get the left or top position w/ respect to the origin.
My question is, how can I get the "normal" position?
Thanks,
mj
Maybe, I misunderstand your question, but wouldn't this just be simple subtraction of the relative offset?
"normal" position is where the element will be positioned with left:0; top:0;. You can get this position by substracting the offset from the current position (tested in Chrome):
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<style type="text/css">
#container { width: 100px; height: 100px; margin: 100px auto; border: 1px solid red; }
#item { position: relative; top: 10px; left: 10px; width: 80px; height: 80px; border: 1px solid green; }
</style>
<script type="text/javascript">
window.onload = function () {
var container = document.getElementById('container');
var item = document.getElementById('item');
var computed = window.getComputedStyle(item);
item.innerHTML = 'Normal: (' + (item.offsetLeft - parseInt(computed.left))
+ ', ' + (item.offsetTop - parseInt(computed.top) + ')');
};
</script>
</head>
<body>
<div id="container"><div id="item"></div></div>
</body>
</html>
to normal position just set position value to: static
position:static

Categories

Resources