CSS variable-height cutout over fixed image backdrop - html

The following code simulates a cutout through an opaque background, scrolling over a fixed image underneath. The height of the cutout is dynamic, sizing to fit its content.
Problem: The code uses a terrible hack! Notice the content Y of the cutout is duplicated in the HTML, though only displayed once in the visual output.
The thing is--the hack "works". Both duplicates are necessary:
If the first is removed, the remaining content Y renders behind the image, no longer visible.
If the second is removed, the cutout collapses to a height of zero, and the remaining content Y overlaps content Z.
Question: Is there a better alternative to this hack, in pure CSS?
<!DOCTYPE html>
<html>
<head>
<title>Simulated Backdrop Image Cutout through Opaque Background</title>
<style>
.opaque-background {
background-color: black;
color: white;
}
.container {
position: relative;
}
.cutout {
background-attachment: fixed;
background-image: url(https://i.stack.imgur.com/RTFBR.jpg);
background-repeat: repeat;
position: absolute;
width: 100%;
height: 100%;
}
</style>
</head>
<body class="opaque-background">
Content preceding (X)
<div class="container">
<div class="cutout">
Content between (Y)
</div>
Content between (Y)
</div>
Content following (Z)
</body>
</html>

Boy do I feel sheepish. The answer is as simple as adjusting the z-index so the cutout renders behind the content Y. (I thought I had already tried that, but apparently not.)
.cutout {
background-attachment: fixed;
background-image: url(https://i.stack.imgur.com/RTFBR.jpg);
background-repeat: repeat;
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
}
The HTML:
Content preceding (X)
<div class="container">
<div class="cutout">
</div>
Content between (Y)
</div>
Content following (Z)

Related

DIV with position:absolute to dynamically extend to bottom of viewport?

Is it possible to specify the max-height of a DIV with position:absolute such that if it would reach past the viewport downwards, a scrollbar appears?
I.e., to user "overflow-y: scroll;" without having to specify the height statically? (Such that it works even if you resize the window.)
Here's what I mean: https://jsfiddle.net/x5efqtv2/2/
(And also see below)
P.S.: I could solve it with JavaScript, I'm interested in pure CSS solutions, if there's any.
Thanks!
div {
border: 1px solid red; /* just to see where the DIVs exactly are */
margin: 5px; /* ditto */
}
.float-over-content {
position: absolute;
max-height: 100px;
overflow-y: scroll; /* works with static max-height only? */
z-index: 10;
background-color: white;
}
<body>
<div id="upper">This one is above the position:absolute one</div>
<div style="position: relative">
<!-- this is needed for position:absolute below to put the div under "upper" -- or so I think -->
<div class="float-over-content">
<!-- I WANT TO DEFINE THE MAX-HEIGHT OF THIS DIV SUCH THAT IF IT REACHES THE BOTTOM OF THE VIEWPORT, A SCROLL BAR SHOULD APPEAR: (AS OPPOSED TO NOW, WHEN ITS HEIGHT REACHES 100px) -->
Make this reach exactly to the bottom<br/>
<!-- X times... -->
Make this reach exactly to the bottom<br/>
</div>
</div>
<div id="lower">
This one is "behind" the position:absolute one (it partially covers this one)
</div>
</body>
What Temani said in the comment. Use the calc function and the view height (vh) of the viewport. Check out the code snippet below. I added a button that will add more lines of text to the element and you can see it expand to fit the viewport with the overflow becoming scroll content.
document.getElementById("add-a-line").addEventListener("click", function(){
document.getElementById("float-over-content").insertAdjacentHTML('afterbegin','Make this reach exactly to the bottom<br/>' );
});
div {
border: 1px solid red; /* just to see where the DIVs exactly are */
margin: 5px; /* ditto */
}
#float-over-content {
position: absolute;
max-height: calc(100vh - 47.4px);
overflow-y: scroll; /* works with static max-height only? */
z-index: 10;
background-color: white;
}
#add-a-line{
position:fixed;
right: 0;
width: 200px;
height: 20px;
background-color: #0f0;
}
<body>
<div id="upper">This one is above the position:absolute one</div>
<div style="position: relative">
<!-- this is needed for position:absolute below to put the div under "upper" -- or so I think -->
<div id="float-over-content">
<!-- I WANT TO DEFINE THE MAX-HEIGHT OF THIS DIV SUCH THAT IF IT REACHES THE BOTTOM OF THE VIEWPORT, A SCROLL BAR SHOULD APPEAR: (AS OPPOSED TO NOW, WHEN ITS HEIGHT REACHES 100px) -->
Make this reach exactly to the bottom<br/>
<!-- X times... -->
Make this reach exactly to the bottom<br/>
</div>
</div>
<div id="lower">
This one is "behind" the position:absolute one (it partially covers this one)
</div>
<div id="add-a-line">
Click to add a line
</div>
</body>

HTML content inside a really tall div

I'd like to create a web page with a really, really large scrollable content area.
However it seems like once the size gets too large browsers stop displaying the full content area correctly. e.g.
<div id="scrollable">
<div id="visCont">
<img src="https://media.glamour.com/photos/5a0399bd8948116a5c05be65/master/w_644,c_limit/kaley-cuoco-the-big-bang-theory-penny-season-11-2017.jpg"> </img>
</div>
<div id="invisibleContent">
<p>
text
</p>
</div>
</div>
#scrollable {
overflow-y:auto;
}
#visCont {
top: 6710000px;
position:absolute;
}
#invisibleContent {
top: 6720000px;
position:absolute;
}
Here if you scroll all the way to the bottom you will see the image and the text displayed fine at the bottom of the div:
https://jsfiddle.net/L7c8bmpm/11/
However here because the content is so far down from the top, the the text is cut off in Chrome, and you don't even get the white div background at the bottom. In IE, it seems like the text isn't displayed and the image is at the very bottom.
https://jsfiddle.net/ww5yu6nh/10/
is there a way to fix this? or is this just a limitation of most web browsers these days as it's not expected that anyone would need a div this tall?
It should all render fine and in my browser (Chrome v65) I can see both elements just fine, but I think your approach is wrong.
Your parent div with id scrollable has a height of 0. Because the elements within are positioned absolute they receive their own stacking context and the parent div collapses. The scrollbar you currently see is actually on the body.
A better approach would be this:
#scrollable {
height: 6720000px;
position: relative;
}
#visCont {
bottom: 1000px;
position: absolute;
}
#invisibleContent {
bottom: 0px;
position: absolute;
}
https://jsfiddle.net/afe6odw3/1/
The scrollbar is still on the body, but your parent div does have an actual height now.
I have edited your code try this one
this is only an example
note tag is no close
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body, html {
height: 100%;
}
.image{
/* Full height */
height: 100%;
width: 100%;
/* Center and scale the image nicely */
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
</style>
</head>
<body>
<img src="https://media.glamour.com/photos/5a0399bd8948116a5c05be65/master/w_644,c_limit/kaley-cuoco-the-big-bang-theory-penny-season-11-2017.jpg" class="image">
<p>
text
</p>
</body>
</html>

CSS - How to create a bg image over 100% with content below window

I am hoping one of you can help. I have a problem that with googling and checking the forums I have not been able to solve.
I would like to create a landing page that has a tall bg image that extends to 100% width and adjusts to the browser window + the dynamic height of the content. All the content should be below the boundary of the browser window so its just the image that can be seen when the browser first loads up and you scroll down to the content which sits over the bottom part of the extended image.
My HTML currently is:
<body>
<section id="sectionOne">
<div id="sectionOneLanding"></div>
<div id="sectionOneContent">CONTENT TO SIT HERE</div>
</section>
</body>
And my CSS is currently:
html,
body {
height:100%;
width:100%;
}
#sectionOne {
height:100%;
background-image: url(../images/cliff.jpg);
background-size: cover;
}
#sectionOneLanding {
height:100%;
width:100%;
}
At the moment, the image crops to 100% browser height and when you scroll down the additional content sits over a white bg instead of the remainder of the image. I believe this is due to the #sectionOne height being 100% but when I set it to higher than 100% it pushes my content further down but still on a white bg. Changing Background-Size to 100% also didn't work. It reacted the same as using cover.
Any ideas? Is there a handy CSS trick?
Apologies if this doesn't make clear sense. Ask any questions you need to as its hard to describe.
You need to use positioning for this case.
html, body {
height: 100%;
margin: 0;
}
#sectionOne {
position: relative;
height: 100%;
background-image: url(../images/cliff.jpg);
background-size: cover;
background-color: #99f;
}
#sectionOneLanding {
height:100%;
width:100%;
}
<section id="sectionOne">
<div id="sectionOneLanding"></div>
<div id="sectionOneContent">CONTENT TO SIT HERE</div>
</section>
You don't need width: 100%. But you need margin: 0; as there are default margins. I have added a background colour so that you can clearly see the background spanning fully leaving the content in the next page.
If you need both the image and the content to be in the same page, the you need to use Flex Box.
FlexBox Example
body, html {
height: 100%;
margin: 0;
}
#sectionOne {
display: flex;
flex-direction: column;
height: 100%;
}
#sectionOneLanding {
background-color: #99f;
flex: 1;
}
<section id="sectionOne">
<div id="sectionOneLanding"></div>
<div id="sectionOneContent">CONTENT TO SIT HERE</div>
</section>
Preview

Make parallaxed element completely opaque

I have the following HTML structure:
<section class="mysection">
<div class="parallax">
<div>
<svg></svg>
</div>
</div>
</section>
<section class="back">
<div class="triangle">
<img src="img/red-triangle-bkgrd.png">
</div>
</section>
This is the CSS in LESS:
.parallax{
width: 90%;
margin-left: auto;
margin-right: auto;
}
section.back {
.triangle {
position: relative;
img {
position: absolute;
right:0;
top: 0;
}
}
}
Before using parallax on the parallax, back just sits immediately below the bottom border of mysection.
When I scale parallax by 1.11111111, the parallax uses 100% width of the viewport. However, back does not sits right beneath the parallax anymore. Instead, it overlaps with the parallax area. Here is a picture of a real-life situation:
How can I make back in the overlap area invisible? Put it another way, how can I make svg or its containers completely opaque without showing the overlaped image beneath it?
I tried 'opacity:1` on svg and its containers, but it is not working.
To be more detailed, I use a tool called ScrollMagic for this work if this is relevant.
You can set the stacking order using z-index. Try setting the following:
.mysection {
position: relative;
z-index: 1;
}
This should ensure that whatever's in your .mysection (such as the svg/map) passes over whatever intersects (assuming you don't apply a greater z-index to the other elements).

Issue setting the position of an element

I am not sure why I am having such an issue with this, but I cannot get a container to show 100% width and have it at the bottom of the parent element.
I am wanting the home-img-text-container2 and its description to be at the bottom of the image container and for it to be 100% width of the image.
Just like where the arrow is:
What I have done is changed the position of the containers to absolute:
#home-img-text-container1, #home-img-text-container2 {
position: absolute;
}
Then modified the width and placed it at bottom:0
#home-img-text-container2 {
bottom: 0;
width: 100%;
}
In addition the before:
#home-img-text-description2:before {
width: 100%;
}
The modifications I made are in the max 640px viewport media query.
What am I doing wrong to not get the container2 div to be placed at the bottom of the image and be 100% of the width of the image?
See the fiddle to see what I have done.
Fiddle
Try this, if you have the home-img-text-container2 element inside of a container, place it out the outside like so
...
</div> <!-- End of main container -->
<div class="home-img-text-container2"></div>
</body>
Then in your css:
.container{
min-height: calc(100vh - 80px);
}
The 80px is the height of whatever your home-img-text-container2 element is I just used 80px as an example. Make sure you have spaces either side of the "-" as well
calc(100vh-80px); will not work
I tried recreating your page and everything worked fine. here is the code:
<html>
<head>
</head>
<body>
<style>
#home-img-text-container1, #home-img-text-container2 {
position: absolute;
}
#home-img-text-container2 {
bottom: 0;
width: 100%;
}
</style>
<div id=home-img-text-description1>
<div id=home-img-text-container2>
Text inside the container2
</div>
</div>
</body>