I know it's not possible with css, but I was trying to find some jQuery solution, so far no luck with answers on stack.
Anyway, the HTML order looks like this, and it needs to stay like this:
<div class="wrapper">
<div style="position:relative;">
<div style="position:relative;">
<div class="dont-want-parents" style="position:absolute;">
</div>
</div>
</div>
</div>
So the question is how to position div with class "dont-want-parents" to the right-bottom of the wrapper div, ignoring all the relative positioned parents.
Thanks to everyone who tried to help, eventually I figured out a solution:
$(window).on("load resize",function(e){
var parentoffset = $('.dont-want-parents').parent();
var elwidth = $('.dont-want-parents').width();
var offset = parentoffset.offset();
$('.dont-want-parents').css('right', -offset.left + elwidth);
});
here's a working fiddle
You can set them all back to static so that the one with absolute ignores them. Also, top and left are needed, as position:absolute only removes the element from the layout but not from its original position.
$('.wrapper > div, .wrapper > div > div').css('position', 'static');
div{
padding: 50px;
background: rgba(255, 0, 0, 0.5);
}
.wrapper{
position: relative;
background: green;
}
.dont-want-parents{
background: blue;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div style="position:relative;">
<div style="position:relative;">
<div class="dont-want-parents" style="position:absolute;">
</div>
</div>
</div>
</div>
Another way is to just yank out the element from wherever it is and put it somewhere that is safe to be absolute.
$('.dont-want-parents').appendTo('.wrapper');
div{
padding: 50px;
background: rgba(255, 0, 0, 0.5);
}
.wrapper{
position: relative;
background: green;
}
.dont-want-parents{
background: blue;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div style="position:relative;">
<div style="position:relative;">
<div class="dont-want-parents" style="position:absolute;">
</div>
</div>
</div>
</div>
Related
Say I wanted an element to be positioned vertically absolutely, but horizontally relative. Is this possible with css/html/javascript?
Not sure which case could be fine to use this mix, but it is possible,
if you only define top/bottom properties in a position:absolute element.
The left/right position of the element will be "relative" if you leave it untouched.
In the following example, the second container has a mixed positioning.
.example{
margin: 30px;
position: relative;
border: 1px solid red;
}
.item1, .item2{
display: inline-block;
margin: 0;
}
#example2 .item2{
position: absolute;
top: 80px;
}
<div id="example1" class="example">
<div class="item1">Item1</div>
<div class="item2">Item2</div>
</div>
<div id="example2" class="example">
<div class="item1">Item1</div>
<div class="item2">Item2</div>
</div>
I have been reading about fixed div's within relative and absolute div's here:
Fix position of div with respect to another div
Fixed positioned div within a relative parent div
Fixed position but relative to container
And many other but none can help me to achive a behavior I have seen in few pages (blogs). I can not remember one at the moment, but here are some images to explain
View 1 & View 2
After scrolling down, the contextual menu sticks to the side of the view and moves down with the scrolling until reach the end of the section in which it stops. If there is more content after it, you can keep scrolling down but the contextual menu no longer follow your view. The same going up, you reach the section, the contextual menu follows you up until the start of the section, then stops and you can keep scrolling up.
Is this posible with only HTML and CSS or do I need a plugin?
Here is a jsFiddle piece of code, perphaps incomplete. Forgot to mention, I'm doing this in Angular 6+ as a component, so I don't have full access to the index.html file with the body tag. The jsFiddle shows what I can work with.
There were a few things going on:
You can set body { position: relative } in your CSS
position: sticky needs a full height column to work. Because your col-6 that was holding your menu was only as tall as it needed to be, it won't scroll.
I moved the p-sticky class to your column.
sticky also needs a top value to know where the element should stick to once it becomes sticky.
.p-sticky {
position: sticky;
top: 60px;
}
body {
position: relative;
}
/*some attemps*/
.p-relative {
position: relative;
}
.p-absolute {
position: absolute;
}
.p-sticky {
position: sticky;
top: 60px;
}
.p-fixed {
position: fixed;
}
/* Standar CSS*/
.navbar {
background-color: blue;
width: 100%;
}
.nav-fixed {
top: 0px;
z-index: 1;
position: fixed;
}
.content-ex1 {
height: 200px;
background-color: green;
}
.content-ex2 {
height: 500px;
background-color: #aaaaaa;
}
.menu {
height: 50px;
background-color: red;
}
<div class="navbar">
some navbar things
</div>
<div class="navbar nav-fixed">
some navbar things
</div>
<div class="content-ex1"> Some content here</div>
<div class="container">
<div class="row">
<div class="col-sm-6 p-sticky">
<div class="menu">menu or something</div>
</div>
<div class="col-sm-6 content-ex2"> Some content here</div>
</div>
</div>
<div class="content-ex1"> Some content here</div>
Here's the fiddle to play around with (which includes your bootstrap):
http://jsfiddle.net/w4mz9dte/
Note: you appear to be using an old version of BootStrap. You may want to update to the newest version. In that case, only a few things will change - namely, you move the p-sticky class to the menu.
Here's the newest version of BS 4.4: http://jsfiddle.net/kamr0bjw/
body {
position: relative;
}
/*some attemps*/
.p-relative{
position:relative;
}
.p-absolute{
position:absolute;
}
.p-sticky{
position:sticky;
top: 60px;
}
.p-fixed{
position:fixed;
}
/* Standar CSS*/
.navbar{
background-color: blue;
width:100%;
}
.nav-fixed{
top: 0px;
z-index:1;
position:fixed;
}
.content-ex1{
height:200px;
background-color: green;
}
.content-ex2{
height:500px;
background-color: #aaaaaa;
}
.menu{
height:50px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/js/bootstrap.min.js"></script>
<div class="navbar">
some navbar things
</div>
<div class="navbar nav-fixed">
some navbar things
</div>
<div class="content-ex1"> Some content here</div>
<div class="container">
<div class="row">
<div class="col-sm-6">
<div class="menu p-sticky">menu or something</div>
</div>
<div class="col-sm-6 content-ex2"> Some content here</div>
</div>
</div>
<div class="content-ex1"> Some content here</div>
So I have this sidebar:
<div class="col-md-3">
<h4 style="color: #404040; font-weight: bold;">
Guides:
</h4>
<div class="sidebar">
<!--auto-generated <ul>...-->
</div>
</div>
And I want it to follow the user as he scrolls down. I know that you can do it with position: fixed; in the styles. But I have a header, so if the div is fixed it remains in that height even if I scroll down.
But if I scroll down, it remains at that fixed point. Here's how it looks like when I scroll down it would look like this:
I want it to remain at the top. I read that I'm supposed to use javascript scroll functions, but I have no clue how, exactly.
You can use position: sticky for an easy "sticky" element. It's a new property, so it doesn't have the best browser support, but easy to use and works well.
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<style>
.row {
height: 200vh;
}
.row:nth-child(odd) {
background: #eee;
}
.sticky-column {
position: sticky;
top: 1em;
}
</style>
<div class="container">
<div class="row">
<div class="col-lg-12">
scroll down
</div>
</div>
<div class="row">
<div class="col-md-3 sticky-column">
<h4 style="color: #404040; font-weight: bold;">
Guides: (look it's sticky!)
</h4>
<div class="sidebar">
<!--auto-generated <ul>...-->
</div>
</div>
</div>
<div class="row"></div>
</div>
try using position: fixed; in style as well as margin-top: -30px; or what ever amount away from top you want:
something like this
<body>
<div class="sidebar" onscroll="dynamicheight()">
</div>
<script>
function dynamicheight() {
var sidebar = document.getElementById("sidebar");
var y = sidebar.scrollTop;
document.getElementById('random').style.height = y;
}
</script>
try something like this
var yOffset = $("#sidebar").offset().top;
$(window).scroll(function() {
if ($(window).scrollTop() > yOffset) {
$("#sidebar").css({
'top': 0,
'position': 'fixed'
});
} else {
$("#sidebar").css({
'top': yOffset + 'px',
'position': 'absolute'
});
}
});
Try this too
position:sticky;
I have 3 questions about my jQuery study today.
Why my jQuery code not have the animation effect as it should be? for example, .slideUp() and .slideDown(), my code shows something strange instead of slideUp animation.
I understand, the .hide() or .slideUp() function is only to HIDE the div box, not DELETE them, however, in my code, why the position of other div boxes changed after a DIV .hide()? Shouldn't it stay at their original position as the DIV box is still there, just HIDED?
How can I achieve to let other DIVs stay at the original position, when one DIV box has been hided?
$(document).ready(function() {
$('#panel1').slideUp(1000).delay(1500).slideDown(1000);
});
.panel {
display: inline-block;
width: 80px;
height: 60px;
border: 1px solid green;
position: relative;
top: 20px;
margin-left: 45px;
border-radius: 5px;
}
.panelTop {
height: 30px;
background-color: blue;
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="panels">
<div id="panel1" class="panel">
<div class="panelTop">#panel1</div>
<div class="panelBottom">content</div>
</div>
<div id="panel2" class="panel">
<div class="panelTop">#panel2</div>
<div class="panelBottom">content</div>
</div>
<div id="panel3" class="panel">
<div class="panelTop">#panel3</div>
<div class="panelBottom">content</div>
</div>
<div id="panel4" class="panel">
<div class="panelTop">#panel4</div>
<div class="panelBottom">content</div>
</div>
</div>
For your first question
Why my jQuery code not have the animation effect as it should be? for
example, .slideUp() and .slideDown(), my code shows something strange
instead of slideUp animation.
The .slideUp() method animates the height of the matched elements. Means it animates height so it reaches 0 (or, if set, to whatever the CSS min-height property is). See here for reference. That is exactly what is happening to your first box it is decreasing in height.
Afterwards the display style property is set to none to ensure that the element no longer affects the layout of the page.
What display none does ?
display:none means that the tag in question will not appear on the
page at all
Now for second and third question
I understand, the .hide() or .slideUp() function is only to HIDE the
div box, not DELETE them, however, in my code, why the position of
other div boxes changed after a DIV .hide()? Shouldn't it stay at
their original position as the DIV box is still there, just HIDED?
How can I achieve to let other DIVs stay at the original position,
when one DIV box has been hided?
The .hide() and .slideUp()function they both add display:none to your tag element. Means they are gone now
Now what can you do to let them stay there, But hidden from view ?
You can use visibility or opacity property instead rather than using display
property.
For example: visibility: hidden; will just hide it from the view.
Will update your fiddle in order to demonstrate it in a while. Hope this will help you. Please feel free to ask if not clear. Thank you.
$(document).ready(function() {
setInterval(function(){
$('#panel1').slideUp(1000).delay(500).slideDown(1000);
}, 3000);
});
.outer-div
{
position: relative;
display: inline-block;
min-height: 1px;
margin-right: 15px;
margin-left: 15px;
width: 130px;
height: 90px;
}
.panel {
border: 1px solid green;
margin-left: 45px;
border-radius: 5px;
position:absolute;
top:0;
width: 100%;
}
.panelTop {
height: 30px;
background-color: blue;
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="panels">
<div class="outer-div">
<div id="panel1" class="panel">
<div class="panelTop">#panel1</div>
<div class="panelBottom">content</div>
</div>
</div>
<div class="outer-div">
<div id="panel2" class="panel">
<div class="panelTop">#panel2</div>
<div class="panelBottom">content</div>
</div>
</div>
<div class="outer-div">
<div id="panel3" class="panel">
<div class="panelTop">#panel3</div>
<div class="panelBottom">content</div>
</div>
</div>
<div class="outer-div">
<div id="panel4" class="panel">
<div class="panelTop">#panel4</div>
<div class="panelBottom">content</div>
</div>
</div>
</div>
You should use display:flex on .panels, that solves your first question.
For second question you should use visibility or opacity.
With current code you are removing it, although it is called hide() it is equivalent to CSS display:none; which doesn't keep space of element.
Although you actually don't need to set visibility in your case because sliding it up will hide element and down show.
Something like this:
$('#panel1').animate({
top: -62 // 60 is height of element plus 2px of borders
}, 1000).delay(1500).animate({
top: 0
}, 1000);
Also you have to change CSS a bit.
Add this to your CSS:
.panels {
display: flex;
overflow: hidden;
margin-top: 20px;
}
And from .panel remove top: 20px;
Full example is here https://jsfiddle.net/_jakob/cphptby3/1/
Note: I am unable to edit the HTML, so I have to find a workaround.
HTML:
<div id="container">
<div id="breadcrumbAds">...</div>
<div id="breadcrumbWrapper">...</div>
<div id="containerTopParsys">...</div>
<div id="leftColWrapper" class="column663Wrapper">...</div>
<div id="rightColWrapper" class="rightColumn663Wrapper">...</div>
<div style="clear:both;"></div>
<div id="containerBottomParsys">...</div>
<div style="clear:both;"></div>
<div id="bgpromo">...</div>
<div style="clear:both;">...</div>
<div style="clear:both;"></div>
</div>
The issue is that all of the divs inside #container, EXCEPT for #leftColWrapper and #rightColWrapper, need to be 100% width of #container, but #leftColWrapper and #rightColWrapper need to be stacked next to each other and centered (together) within the 100% #container, with a max-width of 1224px.
I tried utilizing the following jQuery to add a wrapper div around #left... and #right..., but it ended up grabbing the ads in those containers and placing them in the component where the JS for the page is stored.
(function($) {
$("#leftColWrapper, #rightColWrapper").wrapAll("<div class=\"colWrapper\" />");
})(jQuery);
I either need another solution to wrap those two divs together, so that I can set a max-width of 1224px and center them, or I need to know why this jQuery is picking up those ads and duplicating them within the JS component.
#container{
text-align: center;
font-size: 0;
}
#container > div{
outline: 1px solid #333;
display: inline-block;
min-height: 10px;
text-align: left;
width: 100%;
font-size: 14px;
}
#container #leftColWrapper, #container #rightColWrapper{
width: 50%;
max-width: 612px;
}
<div id="container">
<div id="breadcrumbAds">...</div>
<div id="breadcrumbWrapper">...</div>
<div id="containerTopParsys">...</div>
<div id="leftColWrapper" class="column663Wrapper">width: 50%;<br>
max-width: 612px;</div><div id="rightColWrapper" class="rightColumn663Wrapper">width: 50%;<br>
max-width: 612px;</div>
<div style="clear:both;"></div>
<div id="containerBottomParsys">...</div>
<div style="clear:both;"></div>
<div id="bgpromo">...</div>
<div style="clear:both;">...</div>
<div style="clear:both;"></div>
</div>