Horizontal CSS only parallax effect with layers greater than 100vw - html

How to bootstrap a site with horizontal CSS only parallax effect?
Requirements
CSS only parallax
parent layer must have width/height == 100vw/100vh
child layers must have width/height > 100vw/100vh
child layers must visually align 100% with parent layers width
by now the child layers technically do have 100% of parents width but due to the perspective they visually don't appear to take 100% of parents width
child layers (except the first) must have a top offset relative to its parent
results must base on calculations to have maximum flexibility
must be cross browser solid (at least newest version of majors)
What I have done so far
Actually this question is a follow-up question.
Here's a PEN with my current mockup state in SASS or CSS.
Working Simulated Example (jQuery)
In JavaScript its quite simple to achieve what I'm looking for. So here is a PEN that simulates the effect I'd like to mimic with CSS.
Already known Issues
The issue I'm most concerned about by now is the fact, that browser seem to render this scenario differently. See screenshot of browser window (chrome vs ff) scrolled to the right bottom corner below. But I hope this could be avoided.
There are so many parallax tutorials out there. Why is this different?
Actually I researched really a lot but didn't find not even one description how to implement horizontal parallax (means the child layers have a width > 100vw). Of course there are horizontal parallax scroll tuts out there. But they all have one in common: the child layer widths are always <= 100vw - and thats actually the difference.
html,
body {
height: 100%;
overflow: hidden;
width: 100%;
}
body {
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
#projection {
-webkit-perspective: 1px;
perspective: 1px;
-webkit-perspective-origin: 0 0;
perspective-origin: 0 0;
height: 100%;
overflow: auto;
width: 100%;
}
.pro {
-webkit-transform: scale(1) translate(0px, 0px) translateZ(0px);
transform: scale(1) translate(0px, 0px) translateZ(0px);
height: 100%;
position: absolute;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
width: 100%;
}
.pro--1 {
-webkit-transform: scale(4) translate(0px, 0px) translateZ(-3px);
transform: scale(4) translate(0px, 0px) translateZ(-3px);
width: 110%;
}
.pro--2 {
-webkit-transform: scale(3) translate(0px, 1em) translateZ(-2px);
transform: scale(3) translate(0px, 1em) translateZ(-2px);
width: 110%;
}
.pro--3 {
-webkit-transform: scale(2) translate(0px, 2em) translateZ(-1px);
transform: scale(2) translate(0px, 2em) translateZ(-1px);
width: 110%;
}
.pro {
background: rgba(0, 0, 0, 0.33);
box-shadow: inset 0 0 0 5px orange;
color: orange;
font-size: 4em;
line-height: 1em;
text-align: center;
}
.pro--2 {
box-shadow: inset 0 0 0 5px green;
color: green;
}
.pro--3 {
box-shadow: inset 0 0 0 5px blue;
color: blue;
}
<div id="projection">
<div class="pro pro--1">pro--1</div>
<div class="pro pro--2">pro--2</div>
<div class="pro pro--3">pro--3</div>
</div>

I'm not 100% certain I've gotten exactly what you're targeting, but I've at least got a step forward for you. In this article on pure-css parallax sites, there was an update regarding working around webkit related bugs by using perspective-origin-x: 100% and transform-origin-x: 100%.
If I apply this in both x and y directions to your current mockup case with sass, I end up changing just #projection and .pro to be like this:
#projection
perspective: $perspective + 0px
perspective-origin: 100% 100%
height: 100%
overflow: auto
width: 100%
.pro
#include projection()
height: 100%
position: absolute
transform-origin: 100% 100%
transform-style: preserve-3d
width: 100%
And the parallax behavior starts to look much more like I might expect. Here is the final pen: https://codepen.io/kball/pen/qPbPWa/?editors=0100

Related

Firefox scale down entire web page

Note: There are similar questions (and may be outdated) which do not address the Firefox issue.
I'm using CSS3 to scale down an entire web page by 50%.
#media screen and (max-width: 320px) {
body {
-moz-transform: scale(0.5); /* Moz-browsers */
zoom: 0.5; /* Other non-webkit browsers */
}
}
This works fine in Chrome but Firefox scales it down seemingly 2 times horizontally and vertically.
Is there a new cross-browser solution for properly scaling down?
Cross browser CSS should look like this (IE from ver. 9)
The code is tested in FF 45.0.1 and works fine.
body {
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
-ms-transform: scale(0.5);
-o-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
}
div {
width: 50vw;
height: 50vh;
background: red;
font-size: 40px;
}
<div>
Hello world - font size 40px
</div>

Website is not centering on mobile

im creating simple website. On desktop, whole content is centered ok. It works also with changing size of browser.
But when I visited it on mobile, everything is not centered like on desktop
Take a look: http://piaskownica.lokalnamanufaktura.pl/metod2/
I think that my css wrap class for centering is buggy. Videobackground also is not centered on desktop.
.wrap {
position: absolute;
left: 50%;
top: 50%;
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
width: 90%;
height: 90%;
}
.x2-horizontal has a width of 380px that is too wide for small screens. Watch out for fixed widths in responsive designs.
Your layout method is not ideal. For a start, think of devices that don't support transform.
The video control won't center using margin: auto because of position: absolute. You'd have to use the same kind of centering methos as for the other content (i.e. left: 50% and then pulling it back 50% of its width.)
The issue is that the wrap is getting crushed too small to contain all of the elements. Perhaps you could use a media query to reduce their size on mobile. A simple solution for this case would be
#media (max-width: 600px) {
body {
zoom: .8;
}
}
which would reduce the size of the whole body to 80% so that it doesn't overflow and wrap to new lines. In addition, if you want to center your background video, try changing the bottom and right to 50% instead of 0 in the #video_background, and also add your transform lines onto that.
#video_background {
position: fixed;
bottom: 50%;
right: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1000;
overflow: hidden;
background-size: cover;
transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(50%) translateY(50%);
}

CSS3D translationZ and translationY thinking error

I am making a great thinking mistake here I think.
Please check out this fiddle: http://jsfiddle.net/kimgysen/zdP8q/
I want to understand how to build a spinning cube myself in 3D instead of just copying it, so I'm experimenting; but at the first stage I already get stuck.
First the code:
<section class="container">
<div id="cube">
<figure class="front">1</figure>
<figure class="back">2</figure>
<!--
<figure class="right">3</figure>
<figure class="left">4</figure>
<figure class="top">5</figure>
<figure class="bottom">6</figure>-->
</div>
.container {
width: 200px;
height: 200px;
position: relative;
margin: 0 auto 40px;
border: 1px solid #CCC;
-webkit-perspective: 1000px;
perspective: 1000px;
}
#cube {
margin: 0px;
width: 100%;
height: 100%;
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
-webkit-transform: rotateX( -20deg ) rotateY( 20deg );
transform: rotateX( -20deg ) rotateY( 20deg );
}
#cube figure {
margin: 0px;
display: block;
position: absolute;
width: 196px;
height: 196px;
border: 2px solid black;
line-height: 196px;
font-size: 120px;
font-weight: bold;
color: white;
text-align: center;
}
#cube.panels-backface-invisible figure {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
#cube .front { background: hsla( 0, 100%, 50%, 0.7 ); }
#cube .back { background: hsla( 60, 100%, 50%, 0.7 ); }
#cube .front {
-webkit-transform: translateZ( 100px );
transform: translateZ( 100px );
}
#cube .back {
-webkit-transform: rotateX( 90deg ) translateZ( 100px );
transform: rotateX( 90deg ) translateZ( 100px );
}
What I wonder about is this line:
-webkit-transform: rotateX( 90deg ) translateZ( 100px );
Now this is going to be a very stupid question for you, but still:
Why is it that translateZ moves the figure upwards across the Y-axis?
When changing translateZ into translateY, it is moved across the Z-axis :-s
-webkit-transform: rotateX( 90deg ) translateY( 100px );
Since primary school I thought that: X-axis = horizontal, Y-axis = vertical and Z-axis is the axis that is pendicular on both (ie. pointing towards you).
Can someone please explain to me what's happening? I feel very stupid at this point =s
Yes, the axis work as you say.
But, when you do a rotation, you are not rotaing the object; you are rotating the object space.
So, after a X axis rotation, the z axis can become the y axis. (at 90 deg), can become the z axis inverted (at 180 deg), can become the y axis inverted (at 270 deg), and can revert to z axis at 360 deg.
And, of course, in between it is not aligned with any axis and the movement goes thru a diagonal axis.
Looks like you need a logical starting point to get this sorted out in your head.
Set all your cube sides/panels to position:absolute; and transform-origin: center;
Now we know all our panels will move relative to the same spot, the center of the panel.
So, we make this 3D now by pushing these panels away from it's default Z orientation.
In order to make a cube, we need to translate these panels away from their default Z orientation of 0 (which we need to preserve in order to have a nice anchor to spin on when we animate) by HALF of the width of the panels because... well, geometry.
Now all we need to do is spin these things around the axis with rotateY and rotateX (90deg, 180deg, -90deg) etc.
Then just take the whole thing and animate a spin on it.

Expandable div that's rotated with css

I am trying to create a page layout with a rectangular div on the left side that's rotated 10 degrees, expands with the size of the browser, and doesn't show its edge on the top, left, and bottom. Meaning, the page should appear to be split in the middle on a slant.
My code so far creates the div properly, but when I expand the page you begin to see the edges.
http://jsfiddle.net/jpQvL/1/
HTML
<div id="wrapper">
<div id="right"></div>
</div>
CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#wrapper {
position:relative;
height: 100%;
}
#right {
background: #000;
transition: all 0.5s ease-in-out 0s;
width: 50%;
position: fixed;
min-height: 110%;
transform: rotate(10deg);
top: -73px;
}
The problem is that the tranform property needs render prefixes. You have to add these lines:
-webkit-transform: rotate(10deg);
-moz-transform: rotate(10deg);
-o-transform: rotate(10deg);
-ms-transform: rotate(10deg);
transform: rotate(10deg);
take a look at this
or use one of many prefix-free scripts like this one

How do you align 270deg rotated text to top left?

This should be a very simple problem you would think. I have a box with some title text that I want to rotate -90 degrees. I would like it to be absolutely positioned so that the end of the word is nudged into the top left corner. I can get this to align to the bottom easily enough, but the problem is that with variable length text it seems impossible to have it consistently stay within the container when aligning to the top because things like {top: 0} operate on the title before the transform. For my purposes this only needs work in Firefox. I can use javascript if that is the only solution, but you would think this could be done with just CSS.
You should use transform-origin to adjust the transformation point, along with some creative use of positioning properties.
http://jsfiddle.net/thirtydot/JxEfs/1/
CSS:
#box {
padding: 30px;
position: relative;
border: 1px solid blue;
}
#box > div {
border: 1px solid red;
position: absolute;
top: 0;
right: 100%;
white-space: nowrap;
-webkit-transform: rotate(270deg);
-webkit-transform-origin: right top;
-moz-transform: rotate(270deg);
-moz-transform-origin: right top;
-ms-transform: rotate(270deg);
-ms-transform-origin: right top;
-o-transform: rotate(270deg);
-o-transform-origin: right top;
transform: rotate(270deg);
transform-origin: right top;
}
HTML:
<div id="box">
hello
<div>rotated!</div>
</div>
Can also work without right:100%
Just rotate 270 deg around left top and then translate it back at new 100% width.
transform: rotate(-90deg) translate(-100%, 0);
transform-origin: 0 0;
http://jsfiddle.net/zW7SP/