very strange behaviour of jquery.offset() method - javascript

After doing
$view.offset({
left : X, //X is the same each time
top : this.y
});
console.log($view.offset()); //outputs what it should
for several objects. I saw (in firebug) the following html code
<div id="4017" class="text-block" style="position: relative; top: 2px; left: 22px;">
<div id="4043" class="text-block" style="position: relative; top: 41px; left: -64px;">
<div id="4053" class="text-block" style="position: relative; top: 80px; left: -95px;">
<div id="4081" class="text-block" style="position: relative; top: 119px; left: -135px;">
left should be the same for all divs (and it's displayed so if left is equal for each div). Why left is not the same for each div despite it's shown so that left is the same for all divs?
In CSS I have:
div.text-block {
display: inline-block;
}
Thank you in advance!
UPD: divs are located iside three other divs:
<div id="app-container">
<div id="canvas-container">
<div id="canvas">
<!-- divs are located here -->
</div>
</div>
</div>
In respective CSS I have:
#canvas {
position: absolute;
background-color: white;
width: 100%;
height: 100%;
}
#app-container {
height: auto !important;
min-height: 100%;
}
#canvas-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}

As said in jQuery documentation,
.offset( coordinates )
Description: Set the current coordinates of every element in the set of matched elements, relative to the document.
So if your elements are in other elements not positioned on position (0, 0) relative to the document, there is an offset applied.
EDIT
Relatively positioned inline elements with same left value :

Related

Make an overlay for a horizontally centered image without fixed width

I have this HTML structure:
<div class="container">
<img class="image" />
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
and this CSS code:
.container {
position: relative;
height: 88vh;
margin: 0;
}
.image {
height: 100%;
position: absolute;
margin-right: auto;
margin-left: auto;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
.overlay {
position: absolute;
}
My requirements are as follows:
Make image fill the available vertical space and center it horizontally. (Works)
Make image overlay of the same size as the image - without using an absolute width attribute. (Does not work - problem)
Fix icons to specific spots on the image. (Using percentages for top and left attributes ... Not sure if this is going to be as easy as I currently think.)
How can I have it all - a horizontally centered image expanded to fill the vertical space, an exact overlay and elements fixed to specific spot of the image?
While I would prefer a CSS hack, a Javascript solution will be considered, too, in case the width of the image needs to be transferred to the overlay programmatically.
One way of doing it would be to wrap the Image and the Overlay in a div and center that.
.container {
position: relative;
height: 88vh;
margin: 0;
text-align: center;
}
.imagecontainer
{
position: relative;
display: inline-block;
height: 100%;
}
.image {
height: 100%;
}
.overlay {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
<div class="container">
<div class='imagecontainer'>
<img class="image" src='imageurlhere'/>
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
</div>
Like this, the Image will set the width of its parent and in doing so also the width of the Overlay.

How to prevent get over other divs?

I have a problem...In the following example i don't want that the div who is fixed get over the div with the background red.
Here is the example:
http://jsfiddle.net/HFjU6/3645/
#fixedContainer
{
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
}
Alright, I think I get what the OP wants. He wanted a container that stays fixed on the top of the viewport, but remains confined by a parent. This behaviour is known as a conditional sticky behaviour, and is actually implemented in both Firefox (without vendor prefix) and macOS/iOS Safari (with -webkit- prefix): see position: sticky.
Therefore the easiest (but also the least cross-browser compatible) way is simply to modify your markup, such that the sticky element stays within a parent, and you declare position: sticky on it:
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: -webkit-sticky;
position: sticky;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
transform: translate(-50%, 0); /* Negative left margins do not work with sticky */
}
#div1 {
height: 200px;
background-color: #bbb;
}
#div1 .content {
position: relative;
top: -100px; /* Top offset must be manually calculated */
}
#div2 {
height: 500px;
background-color: red;
}
<div id="div1">
<div id="fixedContainer">I am a sticky container that stays within the sticky parent</div>
<div class="content">Sticky parent</div></div>
<div id="div2">Just another element</div>
An alternative would be to use a JS-based solution. In this case, you do not actually have to modify your markup. I have changed the IDs for easier identification of the elements, however.
The gist of the logic is this:
When the scroll position does not exceed the bottom of the parent minus the outer height of the sticky content, then we do not do anything.
When the scroll position exceeds the bottom of the parent minus the outer height of the sticky content, we dynamically calculate the top position of the sticky content so that it remains visually in the parent.
$(function() {
$(window).scroll(function() {
var $c = $('#sticky-container'),
$s = $('#sticky-content'),
$t = $(this); // Short reference to window object
if ($t.scrollTop() > $c.outerHeight() - $s.outerHeight()) {
$s.css('top', $c.offset().top + $c.outerHeight() - $t.scrollTop() - $s.outerHeight());
} else {
$s.css('top', 0);
}
});
});
* {
margin: 0;
padding: 0;
}
div {
height: 500px;
background-color: red;
}
#sticky-container {
background-color: #bbb;
height: 200px;
}
#sticky-content {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
margin-left: -100px;
left: 50%;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sticky-content">Sticky content that stays within the bounds of #div1</div>
<div id="sticky-container">Sticky confinement area</div>
<div>Other content</div>
Old answer before OP clarified the question appropriately:
Just give them the appropriate z-index values. In this case, you want to:
Do not use static positioning. This can be done by using position: relative for the large elements, in conjunction with the originally position: fixed element.
Assign the appropriate stacking order. The grey <div> element to have the lowest z-index, followed by the position fixed element, and then by the red element.
There are some catchalls to stacking though: the stacking context is reset when you traverse up or down the node tree. For example, the example will not work if the elements are not siblings.
Here is a proof-of-concept example, modified from your fiddle so that inline CSS is removed.
* {
margin: 0;
padding: 0;
}
#fixedContainer {
background-color: #ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px;
z-index: 2;
}
#div1 {
height: 200px;
background-color: #bbb;
position: relative;
z-index: 1;
}
#div2 {
height: 500px;
background-color: red;
position: relative;
z-index: 3;
}
<div id="fixedContainer">z-index: 2</div>
<div id="div1">z-index: 1</div>
<div id="div2">z-index: 3</div>
Just give the z-index.
Hope it helps...
http://jsfiddle.net/HFjU6/1/#run
#fixedContainer {
background-color:#ddd;
position: fixed;
width: 200px;
height: 100px;
left: 50%;
top: 0%;
margin-left: -100px; /*half the width*/
z-index: 2;
}
.div-red {
position: relative;
z-index: 5;
}
<div id="fixedContainer"></div>
<div style="height:200px;background-color:#bbb;"></div>
<div style="height:500px;background-color:red;" class="div-red"></div>

Overlay the Contents of a DIV

I am trying to overlay 2 DIV's in my main parent DIV:
I want to overlay the the second div over on top of the first one. I have a problem overlaying it as I cannot keep it in the middle of the screen.
I have tried this to overlay:
The overlay works fine here, but my container is no longer center when I do this. How can I overlay and keep it center ?
div {
border: 5px solid red;
}
#first {
position: absolute;
z-index: 1;
border-color: orange;
}
#second {
position: absolute;
z-index: 2;
border-color: green;
}
<div id="container" class="container text-center">
<div id="first">Hi</div>
<div id="second">Hello</div>
</div>
Here is what you need to do (see width of both divs and text-align properties):
You can give them background color to see z-index works perfectly :)
#first {
text-align: center;
height: 300px;
width: 100%;
position: absolute;
z-index: 1;
}
#second {
text-align: center;
height: 300px;
width: 100%;
position: absolute;
z-index: 2;
}
<div id="container" class="container text-center">
<div id="first">Hi</div>
<div id="second">Hello</div>
</div>
When you position absolute, the positioned element is taken out of the document flow and positioned relative to the next highest parent element that is not the default position, i.e. not position: static;
The following will cause the absolute positioned children to stay within the containing div:
#container {
position: relative;
}
Your container's text is no longer centered because you have removed its children from the document flow. In essence, it has no content and collapses, and therefore, has no width to which to align the text.
One thing you could do is set the container to position: relative and full-width (i.e. width: 100vw), then set its children to width: 100%.
Then the inner divs will take on the width of their parent.
See this working JSFiddle.
#container {
position: relative;
width: 100%;
height: 100px;
background-color: yellow;
display: flex;
justify-content: center;
align-items: center;
}
#first{
position: absolute;
}
#second{
position: absolute;
}
<div id="container" class="container">
<div id="first">Hi</div>
<div id="second">Hello</div>
</div>
Your main issue is that the divs will not have any relative width to the parent div.
Therefore the text is still technically "centered" in each corresponding div because they're inheriting text-align: center from the container div.
However, the divs' widths will automatically be as wide as they needs to be (i.e. to fit the text, in this case).
You can remedy this one of two ways:
Force the divs to be centered
Give both divs the following (extra) CSS:
left: 50%;
width: 100%;
margin-left: -50%;
This will literally center them in their parent div.
or
Force the divs to be the same size as their parent
Give both the divs the following (extra) CSS:
top: 0;
bottom: 0;
left: 0;
right: 0;
This sets the divs to span their entire parent's height and width.
In both situations, you might need to make the .container class use position: relative, in order for the child divs to have something to be absolute to.
If you're using Bootstrap, there is no need to worry about this, as .container class already has this applied.
Hope one of these solutions helps you :)
Try this style:
#first,
#second {
left: 50%;
transform: translate(-50%, 0);
}
div {
border: 5px solid red;
}
#first {
position: absolute;
z-index: 1;
border-color: orange;
}
#second {
position: absolute;
z-index: 2;
border-color: green;
}
#first,
#second {
left: 50%;
transform: translate(-50%, 0);
}
<div id="container" class="container text-center">
<div id="first">Hi</div>
<div id="second">Hello</div>
</div>

Html5: add image to a parent div and keep the child div images visible

I have a HTML5 code. It has a parent div, and two child div. The parent div takes the whole page and each child div takes half a page. I add some images to the left div and some to the right div. Now I need to add an image to the parent div and keep the images on both left and right child divs visible, i. e I want all images super imposed and visubale.
What is the easiest way of doing this?
Code is like this:
<div id="parent"... >
<div id="leftChild">... </div>
<div id="rightChild">... </div>
</div>
Something like this?
http://moody.es/nons/kek.html
View page source to see the code.
The parent image has position: absolute; and I've the set the children's <img> to have z-index: 1;. When using z-index, the element in question must be positioned, hence the position: relative;
Depending on what you are doing you may need to make parent container relative or you can keep it as it is!
#parent{
width: 100%;
height: 100%;
position: absolute;
background-image: url("http://www.slate.com/content/dam/slate/articles/health_and_science/science/2015/07/150730_SCI_Cecil_lion.jpg.CROP.promo-xlarge2.jpg");
opacity: 0.75;
z-index: 9;
}
#leftChild{
width: 250px;
height: 125px;
position: absolute;
top: 0px;
left: 0px;
background-image: url("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQBUBNygUQANzDPmF45jMi81XQ-nJ70Zw4LGvfpvpTLehLNjWZK8w");
z-index: 0;
}
#rightChild{
width: 250px;
height: 150px;
position: absolute;
top: 0px;
right: 0px;
background-image: url("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSMc12mb4F7OWtwX_r9Sry0SOQgme7GUwXTHVhIipN2WkCWpGZnNQ");
z-index: 0;
}
#parent, #leftChild, #rightChild{
background-repeat: no-repeat;
background-size: 100% 100%;
}
<div id="parent"... ></div>
<div id="leftChild">... </div>
<div id="rightChild">... </div>

Can't initiate Stellar.js from div

I'm trying to implement Stellar.js (http://markdalgleish.com/projects/stellar.js/) to a site that I'm developing. I realised that I need to enclose the parallax scrolling inside a container instead of using window/body in order for it to work on an iPad (considering the viewport) and that's where I run into a problem; the script doesn't seem to initiate correctly.
Here's the structure I've setup on the site -
HTML
<header></header>
<!-- keeping this content outside of #content because of a prefixed alignment -->
<div id="content">
<section id="example" data-stellar-background-ratio="1">
<img src="example-1.png" data-stellar-ratio="2" data-stellar-offset="-25">
<img src="example-2.png" data-stellar-ratio="3" data-stellar-offset="-50">
<img src="example-3.png" data-stellar-ratio="4" data-stellar-offset="0">
</section>
</div>
CSS
#content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
section {
background-attachment: fixed;
width: 100%;
height: 100%;
position: relative;
}
img:first-child {
position: absolute;
top: 0;
left: 300px;
}
img:nth-child(2) {
position: absolute;
z-index: 99;
top: 0;
right: 150px;
}
img:nth-child(3) {
position: absolute;
z-index: 99;
top: 0;
left: 100px;
}
JavaScript
$('#content').stellar({
horizontalScrolling: false
});
I can see that the parallax images inside the section get display: none, but other than that the script doesn't seem to be running. I get no JS errors.
I'm thinking it might have something to do with you using position: absolute and not giving the div any with.
Did you check the size of your #content div? Or does stellar handle this too?

Categories

Resources