I'm trying to get an element to "float" between two other elements by using the position : sticky attribute.
But I'm not getting the desired effect, and I can't figure out why.
I want copy to float between the bottom of upper and the top of lower.
Here is a visual illustration of what I'm trying to achieve
.page {
background-color : grey;
height : 1000px;
position : relative;
}
.container {
background-color : red;
position : absolute;
top : 35%;
height : 300px;
}
.upper {
height : 50px;
}
.copy {
position : sticky;
bottom : 0px;
}
.lower {
height : 50px;
position : absolute;
bottom : 0px;
}
<div class="page">
<div class="container">
<div class="upper">
<h1 class="hero">This is the title</h1>
</div>
<div class="copy">This should float between the upper and lower div</div>
<div class="lower">
<button class="cta">This is a CTA</button>
</div>
</div>
</div>
You're actually really close. You just need to change to use top instead of bottom in the .copy class.
CSS:
.copy {
position: sticky;
top: 16px;
}
Also note that the top value will be the position where the element becomes sticky, so if you want to scroll when it is in the middle of the window, use top: 50vh;.
Update:
It's surprisingly tricky to get position: sticky to work with bottom: 0, but here's a working example.
Related
Is it possible with only CSS to have the following effect:
I have two divs. One follows the other.
Now, if the user starts scrolling down the page (to see other content, more divs if you want..) the second div should "go up" (could also stay fixed and the first div goes down, I mean it would look the same) and overlap the first.
But only overlap for let's say 50px. After that, the behaviour is normal again, meaning that if you scroll further, those divs move out of the browser window eventually.
Have I made myself clear? I can add two coloured boxed to showcase if that helps. I played around a bit and tried parallex/position fixed/sticky mixes, but none seem to work with a given height restriction. I just wonder if this is possible without javascript.
You can get this effect by using position: sticky on both elements. There are a few things that can stop this from taking place, like having overflow: hidden or not having a height set on the parent element.
HTML
<div class="container">
<div class="red-box">This is the red box</div>
<div class="blue-box">this is the blue box</div>
</div>
<!-- needs space to be able to actually scroll on the page -->
<div class="container">
<div class=""></div>
<div class=""></div>
</div>
CSS
/* set the height of the container so that the sticky elements know how far they are meant to scroll */
.container{
min-height: 400px;
}
/* set your position sticky and a attribute that tells it when it should become sticky, in this case right at the top */
.red-box{
height: 400px;
background-color: red;
position: sticky;
top: 0px;
}
.blue-box{
height: 400px;
background-color: blue;
position: sticky;
top: 0px;
}
I have done a quick codepen example so that you can see this working. hope that helps.
https://codepen.io/Domnewmarch/pen/NWzqBde
Solution: I used a combination of negative margin, z-index and position: sticky.
Added margin to the 2nd container to make it more visible.
.sticky-wrapper {
height: 310px;
margin-bottom: -60px;
}
.content {
z-index: -1;
position: sticky;
top: 0;
padding: 0 3%;
height: 250px;
background-color: green;
}
.foo {
margin: 0 50px;
background-color: red;
height: 200px;
}
.next-content {
height: 1000px;
background-color: khaki;
}
<div class="sticky-wrapper">
<div class="content"></div>
</div>
<div class="foo"></div>
<div class="next-content"></div>
As shown in the above picture, the text is showing behind the navbar. It would be great if you please guide me on how I would hide this text from my navbar when I scroll up my content. Should I make a custom class of CSS properties? or if there any built in bootstrap 4 class?
Add a z-index value for your content and navbar. navbar's z-index value must be larger.
The example below will help you understand how it works.
CSS z-index property
example:
div {
position: relative;
width: 100px;
height: 100px;
}
.first-div {
background: red;
/* change this z-index value */
z-index: 2;
}
.other-div {
position: absolute;
background: lime;
top: 60px;
left: 60px;
/* change this z-index value */
z-index: 1;
}
<div class="first-div">
<span>first div</span>
</div>
<div class="other-div">
<span>other div</span>
</div>
I have several divs, each a child of the previous. They're all positioned relative, so that I can offset the children relative to the parents. I want to have the right sides line up, but I can't figure out how. Doing width: 100% obviously doesn't work because it ignores that the divs are not at left: 0.
As you can see, the divs escape the viewport:
div {
position: relative;
width: 100%;
height: 250px;
left: 50px;
top: 50px;
}
#div1 {
background-color: #4286f4;
}
#div2 {
background-color: #3267bc;
}
#div3 {
background-color: #244a87;
}
<div id="div1">
<div id="div2">
<div id="div3">
</div>
</div>
</div>
Or if you prefer: JSFiddle
How can I position the right side of each div at some specific distance from the right side of the screen with only CSS?
This is the expected output (the black rectangle around the outside represents the edges of the screen):
You might consider using margin-left instead of left.
With the CSS box model default, "width and height properties include the content, but does not include the padding, border, or margin," (box-sizing).
Also, block-level elements take up "the full width available", so width:100% isn't necessary (Block-level elements).
body {
margin: 20px 60px 20px 20px;
}
div {
position: relative;
}
div div {
height: 80px;
margin-left: 40px;
top: 40px;
}
#div1 {
background-color: #4286f4;
}
#div2 {
background-color: #3267bc;
}
#div3 {
background-color: #244a87;
}
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
I am trying to put a position:fixed div inside an another div. I want a fixed div which has a width:100%; so it will be great for mobile and desktop at the same time.
Here is my JSfiddle
SF wants some code:
<div id="container">
<div id="item">This div is good div</div>
<div id="fixed">Right side of this div overflow its parent!!! </div>
</div>
An element with position: fixed; ignores the parent size because it is relative only to the viewport:
MDN:
Fixed positioning is similar to absolute positioning, with the exception that the element's containing block is the viewport.
You can:
Try giving it position: absolute; and set the container to position: relative;.
Use position: fixed; and set the size explicitly.
You can use the calc() method to adapt the viewport size. Just subtract right and left margin from the 100%:
Edit: I added a min-height to the body to see the "fixed-effect" on scrolling
body {
margin: 0;
min-height: 1000px;
}
#container {
margin: 10px;
background: black;
color: white;
}
#item {
height: 50px;
width: 100%;
}
#item {
background: blue;
}
#fixed {
height: 50px;
width: calc(100% - 20px);
background: green;
position: fixed;
}
<div id="container">
<div id="item">Normal div</div>
<div id="fixed">Fixed div</div>
</div>
Consider the html and css in this codepen link.
#box2 in the page has been positioned absolute and has a left offset of 200px, so moves 200 px to the right. However, the top offset also gets set to 200px somehow, but if I correctly understand absolute positioning, it should be positioned relative to its parent (body in this case), and so it should have top offset 0.
Can you explain why this happens?
With your css .box you set all boxes 1 - 3 as position: relative.
Your css #box2 sets a absolute positioning on box 2. The css selector for an id (#box2) is more specific than a class selector (.box) and therefore positioning: absolute in #box2 overrules the positioning: relative in .box
You do not define a top property/value in your css for the #box2. That means it will flow with the other tags except for the left position.
Because a div is displayed as block it will display right below #box1. It will be drawn 200px from the left because of your css left: 200px;
Try to change your css for #box2 into something like this
#box_2 { background: #44accf; left: 150px; top: 100px; position: absolute; }
and play around with the left and top values, to understand what the absolute positioning is doing.
You haven't given it a top: value - so it's placing itself where it was if it was relatively positioned/default place (As BoltClock has said, this is known as the static position).
For the purposes of this section and the next, the term "static
position" (of an element) refers, roughly, to the position an element
would have had in the normal flow.
More precisely, the static position
for 'top' is the distance from the top edge of the containing block to
the top margin edge of a hypothetical box that would have been the
first box of the element if its specified 'position' value had been
'static' and its specified 'float' had been 'none' and its specified
'clear' had been 'none'.
~W3 Spec
Here is a basic example:
html,
body {
margin: 0;
padding: 0;
}
.box {
position: relative;
width: 200px;
height: 200px;
}
#box_1 {
background: #ee3e64;
}
#box_2 {
background: #44accf;
left: 200px;
position: absolute;
top: 0;
}
#box_3 {
background: #b7d84b;
}
<div id="box_1" class="box"></div>
<div id="box_2" class="box"></div>
<div id="box_3" class="box"></div>
As you can see, this would also be able to do this using the display:inline-block property (since you're removing the defaulted 'block' styling that take's up 100% of the width), which you then wouldn't need to worry about the absolute at all:
html,
body {
margin: 0;
padding: 0;
}
.box {
position: relative;
width: 200px;
height: 200px;
display: inline-block;
}
#box_1 {
background: #ee3e64;
}
#box_2 {
background: #44accf;
}
#box_3 {
background: #b7d84b;
}
<div id="box_1" class="box"></div>
<div id="box_2" class="box"></div>
<div id="box_3" class="box"></div>
If, however, you needed it to only have two squares wide, you might want to wrap it in a container div width and set a width:
html,
body {
margin: 0;
padding: 0;
}
.box {
position: relative;
width: 200px;
height: 200px;
display: inline-block;
}
#box_1 {
background: #ee3e64;
}
#box_2 {
background: #44accf;
}
#box_3 {
background: #b7d84b;
}
.container{
width:500px;
}
<div class="container">
<div id="box_1" class="box"></div>
<div id="box_2" class="box"></div>
<div id="box_3" class="box"></div>
</div>
So, you were right to think that the absolutely positioned element is aligning to the next available parent with position:relative (which, just so happens to be the body, since you haven't declared one), you have just missed the use of top to position it where you want vertically, and so is defaulting to where 'it would be otherwise' - which is the baseline (which is at the bottom by default in divs)