CSS: parallax effect makes wrapper take bigger size in chrome - css

I've been trying for hours how to fix a bug that is happening only on chrome.
There are 2 layers in a wrapper, which are:
Parallax background
Normal content scrolled
i've been doing parallax effect by using translateZ and scale rules, everything works fine on firefox.. but for some reason which i don't know, on chrome it makes the parent wrapper to take a huge size to fit with the scale from the parallax background.
many posts say that this issue can be fixed by adding translateZ(0) or z-index: 0 to the wrapper but yet it doesn't fix my issue. So the code on CSS for parallax looks like this:
#parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
#parallax__layer--back {
transform: translateZ(-50px) scale(56);
background: url("/assets/images/background.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
background-attachment: fixed;
background-position: center;
scroll-behavior: smooth;
}
HTML where parallax should be positioned:
<body>
<div id="parallax">
<div id="parallax__layer--back" class="parallax__layer "></div>
<div class="parallax__layer parallax__layer--base">
<!-- Base Content -->
</div>
</div>
</body>

Related

Hide scroll bar but scroll with parent div

I'm trying to create a parallax header for my wordpress site, i'm using the divi theme.
Here is my code:
HTML:
<div class="parallax">
<div class="parralax__layer parallax__layer--back">
<img src="https://crispimages.co/wp-content/uploads/2018/05/layer_5.png">
</div>>
<div class="parralax__layer parallax__layer--base">
<img src="https://crispimages.co/wp-content/uploads/2018/05/layer_5.png">
</div>
</div>
CSS:
.parallax {
perspective: 1px;
height: 25vh;
overflow-x: hidden;
overflow-y: auto;
position: relative;
}
.parallax__layer {
position: absolute;
top: 0px;
right: 0;
bottom: 0;
left: 0;
transform-style: preserve-3d;
}
.parallax__layer--base {
transform: translateZ(-1px) scale(2);
}
.parallax__layer--back {
transform: translateZ(-15px) scale(2);
}
My problem is that my header has this seperate scroll bar because it's in its over DIV to the rest of my page, the parallax effect works fine with overflow set to auto, but when I turn it off it breaks the paralax effect.
How do I get the header element to scroll with the rest of my page while still keeping the overflow set to auto?
You can see the problem I'm having here:
https://crispimages.co/home/
you can add the following style rule:
.parallax::-webkit-scrollbar {
display: none;
}
This will solve your problem. But as you can see its vendor prefix dependent. So it will only work in webkit browsers.

cannot center and crop image inside a div box [duplicate]

I know that it is impossible to actually modify an image with CSS, which is why I put crop in quotes.
What I'd like to do is take rectangular images and use CSS to make them appear square without distorting the image at all.
I'd basically like to turn this:
Into this:
A pure CSS solution with no wrapper div or other useless code:
img {
object-fit: cover;
width: 230px;
height: 230px;
}
Assuming they do not have to be in IMG tags...
HTML:
<div class="thumb1">
</div>
CSS:
.thumb1 {
background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
width: 250px;
height: 250px;
}
.thumb1:hover { YOUR HOVER STYLES HERE }
EDIT: If the div needs to link somewhere just adjust HTML and Styles like so:
HTML:
<div class="thumb1">
Link
</div>
CSS:
.thumb1 {
background: url(blah.jpg) 50% 50% no-repeat; /* 50% 50% centers image in div */
width: 250px;
height: 250px;
}
.thumb1 a {
display: block;
width: 250px;
height: 250px;
}
.thumb1 a:hover { YOUR HOVER STYLES HERE }
Note this could also be modified to be responsive, for example % widths and heights etc.
If the image is in a container with a responsive width:
.rect-img-container {
position: relative;
}
.rect-img-container::after {
content: "";
display: block;
padding-bottom: 100%;
}
.rect-img {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="rect-img-container">
<img class="rect-img" src="https://picsum.photos/id/0/367/267" alt="">
</div>
(edit: updated from sass to plain css)
(edit: Added dummy image for reference)
Place your image in a div.
Give your div explicit square dimensions.
Set the CSS overflow property on the div to hidden (overflow:hidden).
Put your imagine inside the div.
Profit.
For example:
<div style="width:200px;height:200px;overflow:hidden">
<img src="foo.png" />
</div>
Using background-size:cover - http://codepen.io/anon/pen/RNyKzB
CSS:
.image-container {
background-image: url('http://i.stack.imgur.com/GA6bB.png');
background-size:cover;
background-repeat:no-repeat;
width:250px;
height:250px;
}
Markup:
<div class="image-container"></div>
I actually came across this same problem recently and ended up with a slightly different approach (I wasn't able to use background images). It does require a tiny bit of jQuery though to determine the orientation of the images (I' sure you could use plain JS instead though).
I wrote a blog post about it if you are interested in more explaination but the code is pretty simple:
HTML:
<ul class="cropped-images">
<li><img src="http://fredparke.com/sites/default/files/cat-portrait.jpg" /></li>
<li><img src="http://fredparke.com/sites/default/files/cat-landscape.jpg" /></li>
</ul>
CSS:
li {
width: 150px; // Or whatever you want.
height: 150px; // Or whatever you want.
overflow: hidden;
margin: 10px;
display: inline-block;
vertical-align: top;
}
li img {
max-width: 100%;
height: auto;
width: auto;
}
li img.landscape {
max-width: none;
max-height: 100%;
}
jQuery:
$( document ).ready(function() {
$('.cropped-images img').each(function() {
if ($(this).width() > $(this).height()) {
$(this).addClass('landscape');
}
});
});
Check out CSS aspect-ratio
https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
.square-image{
width: 50%;
background-image: url('https://picsum.photos/id/0/367/267');
background-size: cover;
background-position: center;
aspect-ratio: 1/1;
}
<div class="square-image"></div>
You can also do this with a regular img tag as follows
.square-image{
width: 50%;
object-fit: cover; /* Required to prevent the image from stretching, use the object-position property to adjust the visible area */
aspect-ratio: 1/1;
}
<img src="https://picsum.photos/id/0/367/267" class="square-image"/>
Today you can use aspect-ratio:
img {
aspect-ratio: 1 / 1;
}
It has wide support amongst modern browsers as well:
https://caniuse.com/mdn-css_properties_aspect-ratio
object-fit: cover will do exactly what you need.
But it might not work on IE/Edge. Follow as shown below to fix it with just CSS to work on all browsers.
The approach I took was to position the image inside the container with absolute and then place it right at the centre using the combination:
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Once it is in the centre, I give to the image,
// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;
// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;
This makes the image get the effect of Object-fit:cover.
Here is a demonstration of the above logic.
https://jsfiddle.net/furqan_694/s3xLe1gp/
This logic works in all browsers.
Original Image
Vertically Cropped
Horizontally Cropped
Square Container
I had a similar issue and could not "compromise" with background images.
I came up with this.
<div class="container">
<img src="http://lorempixel.com/800x600/nature">
</div>
.container {
position: relative;
width: 25%; /* whatever width you want. I was implementing this in a 4 tile grid pattern. I used javascript to set height equal to width */
border: 2px solid #fff; /* just to separate the images */
overflow: hidden; /* "crop" the image */
background: #000; /* incase the image is wider than tall/taller than wide */
}
.container img {
position: absolute;
display: block;
height: 100%; /* all images at least fill the height */
top: 50%; /* top, left, transform trick to vertically and horizontally center image */
left: 50%;
transform: translate3d(-50%,-50%,0);
}
//assuming you're using jQuery
var h = $('.container').outerWidth();
$('.container').css({height: h + 'px'});
Hope this helps!
Example:
https://jsfiddle.net/cfbuwxmr/1/
Use CSS: overflow:
.thumb {
width:230px;
height:230px;
overflow:hidden
}
Either use a div with square dimensions with the image inside with the .testimg class:
.test {
width: 307px;
height: 307px;
overflow:hidden
}
.testimg {
margin-left: -76px
}
or a square div with a background of the image.
.test2 {
width: 307px;
height: 307px;
background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
Here's some examples: http://jsfiddle.net/QqCLC/1/
UPDATED SO THE IMAGE CENTRES
.test {
width: 307px;
height: 307px;
overflow: hidden
}
.testimg {
margin-left: -76px
}
.test2 {
width: 307px;
height: 307px;
background: url(http://i.stack.imgur.com/GA6bB.png) 50% 50%
}
<div class="test"><img src="http://i.stack.imgur.com/GA6bB.png" width="460" height="307" class="testimg" /></div>
<div class="test2"></div>
I came with a different approach. You basically have to crop the rectangular image to fit it inside the square is all there is to it. Best approach is if the image width is greater than the height, then you crop the image alittle from left and right side of the image. If the image height is greater than the image width then you crop the bottom of the image. Here is my solution. I needed a little help from PHP though.
<div style="position: relative; width: 154px; height: 154px; overflow: hidden;">
<?php
//get image dimmensions whichever way you like. I used imgaick
$image = new Imagick("myimage.png");
$width = $image->getImageWidth();
$height = $image->getImageHeight();
if($width > $height){
?>
<img src="myimage.png" style="display: block; position: absolute; top: 0px; left: 50%; transform: translateX(-50%); -ms-transform: translateX(-50%); -webkit-transform: translateX(-50%); height: 100%; " />
<?php
}else{
?>
<img src="myimage.png" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; " />
<?php
}
?>
</div>

Scale image maintaining aspect ratio, then center vertically and horizontally inside fluid height and width DIV

OK, this is a bit of a mouthful and very super specific. I will try my best to explain!
The goal is to maintain aspect ratio while scaling an image and keeping it vertically and horizontally centred inside a DIV that is defined only by percentages. The image needs to maintain best fit, so if max width is required then it's used and vice versa.
Use Firefox version 33 (or a few earlier versions) to view this js fiddle to see it working properly:
http://jsfiddle.net/3vr9v2fL/1/
HTML:
<div id="imageviewer" >
<div class="dummy"></div>
<div class="img-container centerer" id="imagevieweroriginal">
<img class="centered" src="http://chrisnuzzaco.com/couch/uploads/image/gallery/smiling_woman_wearing_drivers_cap.jpg" alt="Doctor Concentrating on Work"></img>
</div>
</div>
</div>
CSS:
#imagewrapper{
position:absolute;
width:69%;
height:100%;
top:0px;
bottom:0px;
background-color:gray;
}
#imageviewer{
position:relative;
width:100%;
height:100%;
}
.responsive-container {
position: relative;
width: 100%;
border: 1px solid black;
}
.dummy {
padding-top: 100%; /* forces 1:1 aspect ratio */
}
.img-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.centerer {
text-align:center; /* Align center inline elements */
font: 0/0 a; /* Hide the characters like spaces */
}
.centerer:before {
content: ' ';
display: inline-block;
vertical-align: middle;
height: 100%;
}
.centered {
vertical-align: middle;
display: inline-block;
max-height: 100%;
max-width: 100%;
}
The Problem:
I originally found my code here on stackoverflow and made a simple mod adding max-height/width to the .centered class. At the time, this worked in all major browsers. The only exception being Opera.
Vertically align an image inside a div with responsive height
There is a big problem however: the latest version of Chrome (Version 38.0.2125.111) no longer works with this code and my users prefer chrome to other browsers by a large margin.
Any ideas on how to solve this? Is this a bug with Chrome? I'm open to javascript suggestions to make this work again.
I came up with this: JSFiddle - centered image keeps aspect ratio in resizable fluid container
.container {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
.image {
position: absolute;
max-width: 100%;
max-height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
body {
width: 100%;
height: 100%;
position: absolute;
margin: 0;
}
<div class='container'>
<img class='image' src='http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample1_l.jpg'>
</div>
The image stays centered both horizontally and vertically. If the window is scaled down the image shrinks respecting original aspect ratio.
I didn't test it on all browsers though.
Take a look at CSS object-fit property:
You may need a polyfill for older browsers, though.
View browser support for object-fit.

Issues with overflow:hidden in Chrome on a 'retina' display

I have a CSS problem that only occurs in Google Chrome. Objects set to overflow: hidden are being 'clipped' at the edges when within a horizontally centred container, and only at
odd browser widths, and only on a high-res display.
HTML:
<html><body>
<div id="container">
<div class="sprite"> </div>
</div>
</body></html>
CSS:
#container
{
margin: 0 auto;
max-width: 800px;
-webkit-transform: translate3d(0px,0px,0px);
}
.sprite
{
width: 30px;
height: 30px;
overflow: hidden;
position: relative;
}
.sprite:after
{
content: ' ';
overflow: hidden;
display: block;
width: 30px;
height: 30px;
position: absolute;
top: 0;
left: 0;
background-image: url("/img/sprite#2x.png");
background-position: 0 0;
background-repeat: no-repeat;
-webkit-background-size: 30px 30px;
-moz-background-size: 30px 30px;
-o-background-size: 30px 30px;
background-size: 30px 30px;
}
Now, as I resize the width of the window, at odd window widths the sprite gets clipped either side on my retina display. It does not occur on a standard (1 css pixel to 1 display pixel) display.
This apparent rendering bug does not occur in Safari or Firefox. This is on OS X 10.9.3 running Chrome 35.
Edit: It also happens with a pure CSS circle shape, so doesn't seem related to the use of a background image.
My example was too over-simplified so the problem didn't occur standalone.
It turns out that, via a SASS mixin in my full application, I had the following applied to the panel containing the sprite (edit question to include it)
-webkit-transform: translate3d(0px,0px,0px);
This was there to improve CSS performance with hardware acceleration where available (mainly iOS).
Removing this improves the situation slightly, so it seems less likely to 'clip' the shape when resizing the window.
However removing overflow: hidden from the :after element seems to have solved it entirely.
It is worth noting that this 'clipping' side-effect occurs even with a pure CSS circle, it's not related to background-images (thanks #Rohit).
This seems to be a rendering bug rather than something I'm doing wrong.
Hey now you can try this with out image
Css
#container
{
margin: 0 auto;
}
.sprite
{
width: 30px;
height: 30px;
position: relative;
text-align:center;
line-height:30px;
font-weight:bold;
}
.sprite:after
{
content: ' ';
overflow: hidden;
display: block;
position: absolute;
top: 0;
left: 0;
right:0;
bottom:0;
background:#eecc00;
border-radius:50%;
z-index:-1;
}
HTML
<div id="container">
<div class="sprite">! </div>
</div>
Demo

translate3d() causes clipping in Safari

I have a web app that I am developing that relies heavily on absolute positioning, CSS transforms, and CSS transitions.
My markup:
<div class="wrapper">
<div class="background" ></div>
<div class="foreground" >
<div class="image" ></div>
</div>
</div>​
My CSS
.wrapper{
-webkit-perspective: 1600;
-webkit-perspective-origin-y: 30%;
height: 500px;
width: 100%;
}
.background{
position: absolute;
background-size: 100% 100%;
background-image: url("http://farm9.staticflickr.com/8321/8038059897_403c567211.jpg");
background-color: transparent;
position: absolute;
width: 100%;
height: 300px;
bottom: 0;
pointer-events: none;
-webkit-transform:translate3d(0px,0px,0px);
}
.foreground{
position: absolute;
top: 5%;
bottom: 5%;
left: 5%;
right: 5%;
-webkit-transform: rotateY(25deg);
}
.foreground .image{
background-image: url("http://farm7.staticflickr.com/6139/6198476123_754eaa1920_m.jpg");
position: absolute;
background-size: 100% 100%;
min-width: 100%;
min-height: 100%;
-webkit-transform:translate3d(0px,10px,0px);
}
You can see it in action at http://jsfiddle.net/KjG3f/24/
If you look at the example in Safari (both desktop and iOS), you'll see that the foreground image is clipped by the background. In Chrome, however, it seems to work correctly.
Removing the translate3d() from the background seems to cause rendering to work, but I require the translate3d() to be there for animation purposes.
Preemptive thanks for help.
​
I'd consider this a bug in Chrome, and indeed there are two issues open regarding it (http://code.google.com/p/chromium/issues/detail?id=116710 and http://code.google.com/p/chromium/issues/detail?id=102673). Firefox exhibits the same behavior.
The Safari way of doing it makes sense...when you rotate the foreground image in a 3D space, it should clip through the image behind it, as they're on the same plane. If you change the translate3d Z-value on either the foreground or background elements, you can move them forward or backwards to where they don't intersect.
Cross-browser support for 3D transforms is unfortunately still pretty weak, good luck!

Resources