Pure CSS Parallax additional space problem [duplicate] - css

This question already has an answer here:
Pure CSS-Parallax: Inconsistent Scrolling between Firefox and Chrome
(1 answer)
Closed last year.
What I want to achieve
I want to add a parallax effect to a single fullscreen section with dynamic content (has not fixed height) and a background.
I would like that on a scroll the background would move slower than the content and that the background would be high enough to cover the whole content.
What I've tried
To achieve that I have:
set perspective: 10px to .root
set transform: translateZ(-10px) scale(2) to .background
put .background into .container and set it's position to absolute so it has the container's height (which is dependent on content's height)
Problem
The problem is that when I scroll down to the bottom I can see:
bottom of the .content
a piece of a .background
a black piece of body's black background (appears on Chrome)
When I would scroll down to the bottom I would like that the .content would be the end of the screen and that I wouldn't see anything else beneath it.
Code
body { margin: 0; background: #000; }
.wrapper {
height: 100vh;
overflow: scroll;
perspective: 10px;
}
.container {
position: relative;
transform-style: preserve-3d;
}
.content {
display: flex; flex-direction: column; justify-content: space-between;
height: calc(100vh + 100px);
padding: 20px 0;
background: rgba(255, 0, 0, 0.2);
text-align: center;
}
.background {
position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1;
background-image: linear-gradient(cyan, pink);
transform: translateZ(-10px) scale(2);
}
<div class="wrapper">
<div class="container">
<div class="content">
<p>top content</p>
<p>center content</p>
<p>bottom content</p>
</div>
<div class="background"></div>
</div>
</div>
Question
How can I achieve it?
I have no idea how can I make it work.
Please help

Something like this?
body { margin: 0; background: #000; }
.wrapper {
height: 100vh;
overflow: scroll;
perspective: 10px;
}
.container {
position: relative;
transform-style: preserve-3d;
}
.content {
display: flex; flex-direction: column; justify-content: space-between;
padding: 20px 0;
background: rgba(255, 0, 0, 0.2);
text-align: center;
}
.content p {
height: 100vh;
}
.background {
position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1;
background-image: linear-gradient(cyan, pink);
}
<div class="wrapper">
<div class="container">
<div class="content">
<p>top content</p>
<p>center content</p>
<p>bottom content</p>
</div>
<div class="background"></div>
</div>
</div>

Related

How can I fix a div relative to a scrollable container?

Please see this minimum example
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow: scroll;
}
.box {
width: 100%;
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.loading-cover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="loading-cover">
Loading
</div>
<div class="box"></div>
</div>
I want to fix the white overlay when scrolling.
I've tried inset: 0 or width: 100%;height:100%; on loading-cover, but no luck.
position: sticky; is also unusable in this case because it sticks to the window viewport, not the scrollable container.
Is there any way I can solve this problem?
This might not be the shortest path to a solution, but it does work. It might hold up in cross-browser testing if you don't need to support IE.
This is using a loading class on the container that applies a sticky ::before pseudo-element, with a negative bottom margin to make the content pop up underneath it. A little goofy, but it's a weird situation. I also removed some unnecessary width values and changed overflow to overflow-y, which may or may not be useful in your situation.
With this, you could turn on and off the "Loading" message by adding or removing the class to the container.
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow-y: scroll;
}
.box {
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.container.loading::before {
position: sticky;
top: 0;
height: 200px;
margin-bottom: -200px;
background: white;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
content: 'Loading';
}
<div class="container loading">
<div class="box"></div>
</div>

How to make a fixed position div in center [duplicate]

This question already has answers here:
Center aligning a fixed position div
(16 answers)
How can I center an absolutely positioned element in a div?
(37 answers)
Closed 2 years ago.
I have two 50% width divs and want to make a div(which is inside one of them) to be position fixed and center.
I have created a codepen. Please have a look at it to get a better idea about the problem. Also I have embed my code here as well.
<div class="parent">
<div class="first">
<p>...</p>
</div>
<div class="second">
<p>...</p>
<div class="floating"></div>
</div>
</div>
.parent {
display: flex;
width: 100%
}
p {
color: #fff;
padding: 20px;
}
.first {
width: 50%;
height: 100vh;
background-color: #000;
}
.second {
width: 50%;
height: 100vh;
background-color: #ddd;
}
.floating {
width: 100px;
height: 100px;
background-color: #fff;
position: fixed;
}
PS I know its possible with position sticky but I don't want to use it. You can add the below code in .floating class and it will be in center.
position: sticky;
margin: 0 auto;
Use transform: translate(-50%) with left: 50%:
.centered {
background: forestgreen;
width: 400px;
height: 100px;
position: fixed;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
<div class="centered"></div>
`
Set the position relative to second element and than set the box in center with position absolute like this:
.second {
position: relative;
width: 50%;
height: 100vh;
background-color: #ddd;
}
.floating {
width: 100px;
height: 100px;
background-color: #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
You can use position:
<div class="parent">
<div class="first">
</div>
<div class="second">
</div>
<div class="floating"></div>
</div>
You can show full code in JSFIDDLE

Parallax background image fit div

I'm trying to create a parallax background as a separator for a site. The background image seems to be only taking up about half of the size it should be with a strange white border all around it. I can't seem to find anything in my code that might be causing this and no matter what I do I either have the border, or scroll bars on the inside div. I just need the background image to fit the space of the div to make a scrolling parallax in that section.
I've tried overflow:hidden playing with various height/width combinations including calc(100vh * 2) to make the image larger. The only thing it seems to do is change the image in the container it appears in (almost like a sub container but there isn't a sub-container on it). I've also played with the transform, transform-origin, perspective, scale, and anything else I could find on google and here.
html, body {
height: 100%!important;
margin: 0px;
padding: 0px;
}
input, select, textarea {
box-shadow: inset 0 2px 4px hsla(0, 0%, 0%, 0.13);
}
.ico {
width: 50px!important;
height: 50px!important;
}
nav {
position: fixed!important;
z-index: 999;
width: 100vw;
}
.content_head {
background-color: aqua;
}
.content_about {
background-color: blueviolet;
}
.content_spacer {
opacity: 0;
height: 50vh;
}
.back_spacer {
opacity: 0;
}
.back1 {
background-image: url("images/IMG_1164.JPG");
background-clip: border-box;
background-size: cover;
height: 100%!important;
width: 100%!important;
min-height: 100%!important;
min-width: 100%!important;
}
.back-group {
max-height: 75vh!important;
}
.container-fluid {
padding: 0!important;
}
/* Parallax Styles Credit to: https://keithclark.co.uk/articles/pure-css-parallax-websites */
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
transform-origin-x: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax__layer--base {
transform: translateZ(0);
height: 100vh;
}
.parallax__layer--back {
position: absolute;
width: 30%!important;
height: 50vh!important;
top: 0;
right: 0;
bottom: 0;
left: auto;
margin: 0;
transform: translateZ(-1px);
-webkit-transform-origin-y: 100% 100% 0px;
-moz-transform-origin: 100% 100% 0px;
-ms-transform-origin: 100% 100% 0px;
transform-origin: 100% 100% 0px;
}
.parallax__group {
position: relative;
height: 100vh;
transform-style: preserve-3d;
overflow: auto!important;
}
<div class="parallax">
<div class="parallax__group">
<div class="parallax__layer--base content_head">
<h1 class="text-center my-auto">Content base</h1>
</div>
</div>
<div class="parallax__group back-group">
<div class="parallax__layer--back back1"></div>
<div class="parallax__layer--base content_spacer"></div>
</div>
<div class="parallax__group">
<div class="parallax__layer--base content_about">
<h1 class="text-center my-auto">Content base 2</h1>
</div>
</div>
<div class="parallax__group">
<div class="parallax__layer--back back">
<div class="parallax__layer--base content_spacer"></div>
<img src="images/IMG_1170.JPG" height="4096" width="3072" class="img-fluid"/>
</div>
</div>
</div>
Strictly speaking, I suppose it isn't actually a border, but more that the background image is smaller than the DIV element as a whole.
body,
html {
margin: 0;
padding: 0;
}
.wrapper {
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 2px;
}
.section {
position: relative;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: white;
text-shadow: 0 0 5px #000;
}
.parallax::after {
/* Display and position the pseudo-element */
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: translateZ(-1px) scale(1.5);
background-size: 100%;
z-index: -1;
}
.static {
background: red;
}
.bg1::after {
background-image: url('https://images.unsplash.com/photo-1567170578400-9d182981f2a1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80');
}
.bg2::after {
background-image: url('https://images.unsplash.com/photo-1567170566770-eea3bb0b16ed?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80');
}
<main class="wrapper">
<section class="section static">
<h1>Static</h1>
</section>
<section class="section parallax bg1">
<h1>Parallax</h1>
</section>
<section class="section static">
<h1>Static</h1>
</section>
<section class="section parallax bg2">
<h1>Parallax</h1>
</section>
<section class="section static">
<h1>Static</h1>
</section>
</main>

How to center an image within a div (both vertical and horizontal) and cut off excess?

Is it possible in CSS to achieve the following:
With the following being the html and css:
<div class="preview">
<img src="/big-ass-image.png" width="150" height="500" border="0"/>
</div>
.preview {
width: 200px;
height: 100px;
}
So that only the part of the image in the div (gray box in the mockup above) is showing, and the middle part of the image is shown with the rest cut off.
Hopefully this helps you with your query. If you have any questions, drop a comment and I'll try to amend my post to suit your needs.
.preview {
background: red;
width: 200px;
max-height: 100px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.preview:hover {
overflow: visible;
}
.preview img {
width: 150px;
}
<div class="preview">
<img src="http://placehold.it/150x150">
</div>
One solution would be to use position: absolute on image and center it with transform: translate and set overflow: hidden on parent.
.preview {
width: 200px;
height: 50px;
border: 1px solid black;
position: relative;
overflow: hidden;
margin: 50px;
}
img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: -1;
}
.preview:hover {
overflow: visible
}
<div class="preview">
<img src="http://placehold.it/150x150">
</div>

Angular 2 Material - How To Center Progress Spinner

I have implemented the Angular 2 progress spinner from the below link
https://github.com/angular/material2/tree/master/src/lib/progress-spinner
I would like to have it centered, however, the only way I can seem to get it to work is to remove the
display: block
from the CSS. However, this causes the spinner to appear huge on the page.
Any advice would be great.
just add margin rule:
<md-progress-spinner style="margin:0 auto;"
mode="indeterminate"></md-progress-spinner>
plunker: http://plnkr.co/edit/sEiTZt830ZE7rqjq9YXO?p=preview
UPDATE
Just wanted to share and demonstrate 6 other general centering solutions
FLEX:
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* +++++++ STYLES +++++++ */
.wrapper {
height: calc(100vh - 20px);
background: red;
}
.inner {
background: green;
color: white;
padding: 12px;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
GRID:
.center {
display: grid;
place-items: center;
}
/* +++++++ STYLES +++++++ */
.wrapper {
height: calc(100vh - 20px);
background: red;
}
.inner {
background: green;
color: white;
padding: 12px;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
LINE HEIGHT + TEXT ALIGN (will not work as desired for multiple lines, use white-space: nowrap; to ensure one line)
.center {
line-height: calc(100vh - 20px);
text-align: center;
}
/* +++++++ STYLES +++++++ */
.wrapper {
background: red;
white-space: nowrap;
}
.inner {
background: green;
color: white;
padding: 12px;
display: inline;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
USING ABSOLUTE, TOP, LEFT and TRANSFORM TRANSLATE
.center.wrapper {
position: relative;
}
.center .inner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* +++++++ STYLES +++++++ */
.wrapper {
height: calc(100vh - 20px);
background: red;
}
.inner {
background: green;
color: white;
padding: 12px;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
USING ABSOLUTE, TOP, LEFT, BOTTOM, RIGHT and MARGIN AUTO (mentioned by György Balássy). Note: inner div width needs to be set.
.center.wrapper {
position: relative;
}
.center .inner {
position: absolute;
inset: 0;
margin: auto;
}
/* +++++++ STYLES +++++++ */
.wrapper {
height: calc(100vh - 20px);
background: red;
}
.inner {
background: green;
color: white;
padding: 12px;
height: max-content;
width: max-content;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
Using TABLE
.center {
display: table-cell;
text-align: center;
vertical-align: middle;
}
/* +++++++ STYLES +++++++ */
.wrapper {
height: calc(100vh - 20px);
width: calc(100vw - 20px);;
background: red;
}
.inner {
background: green;
color: white;
padding: 12px;
display: inline-block;
}
<div class="wrapper center">
<div class="inner">INNER CONTENT</div>
</div>
This CodePen helped me to create a page-centered spinner with Material Design in Angular 4: https://codepen.io/MattIn4D/pen/LiKFC
Component.html:
<div class="loading-indicator">
<mat-progress-spinner mode="indeterminate" color="accent"></mat-progress-spinner>
</div>
Component.css:
/* Absolute Center Spinner */
.loading-indicator {
position: fixed;
z-index: 999;
height: 2em;
width: 2em;
overflow: show;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
/* Transparent Overlay */
.loading-indicator:before {
content: '';
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.3);
}
The first answer doesn't work unless height is set in a parent element.
I fixed it using fxFlex
<div fxLayout="row" fxLayoutAlign="space-around center" style="height:100%">
<mat-spinner diameter="50" strokeWidth="5"></mat-spinner>
</div>
I am using angular 6 with material 2+ and used that CSS code:
.mat-spinner {
position: relative;
margin-left: 50%;
margin-right: 50%;
}
Source: Angular Wiki
For me, this worked the best:
Component:
<div class="center">
<mat-spinner> </mat-spinner>
</div>
Scss:
/** Can be used to center any element */
.center {
left: 50%;
position: absolute;
top: 50%;
transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
}
you can use with grid as well :
.wrapper {
display: grid;
place-content: center;
height: calc(100vh - 20px);
background: red;
}

Resources