So I'm learning CSS transitions and transforms and am trying to make a simple slider in CodePen. The basic idea is that I have one div on top of another and I want the first one to slide off the second when hovered on. It works fine without any overflow property, but once I added overflow: hidden to the underlying square, it pushes the overlying square down. Why is this?
http://codepen.io/johnnycopes/pen/BKReOq
--- HTML ---
<div class="container">
<div class="shape">
<div class="shape-cover">
</div>
</div>
</div>
--- CSS ---
body {
font-family: Verdana;
background: #fff0a5;
}
.container {
margin: 0 auto
}
.shape {
margin: 50px auto 0;
width: 200px;
height: 200px;
overflow: hidden;
background: #ffb03b;
}
.shape-cover {
margin: 50px auto 0;
height: 200px;
width: 200px;
background: #468966;
transform: translateX(0%);
transition: transform .5s ease-in-out;
}
.shape-cover:hover {
transform: translateX(100%);
}
It is because you are using a margin on the "overlaying square".
shape-cover is inside the shape, so the margin of the shape-cover will me relative to its parent.
So try removing the margin on the shape-cover div.
Related
How is it possible to make this transition in css the last transition of this gif: https://cdn.dribbble.com/users/757683/screenshots/4317968/dribbble_spec_1_v4.gif
The last one, I put a image here:
Start showing pyramid gradually, and slide it to right releasing the login details on the left.
You can do something like:
The whole parent div shall be bigger than 100vw e.g: 120vw.
The body shall have overflow-x: hidden,
The img should be 100vw while the sign-in part a bit smaller eg: 20vw,
The parent div should be translated in such a way that the img is only visible at the beginning, then we would animate the parent div to be translated to show the sign-in part as well.
Enough of theory, understand from the code below:
* {
margin: 0;
padding: 0;
}
body {
overflow-x: hidden;
}
.parent_container {
display: flex;
width: 120vw;
animation: anime 2s;
}
#keyframes anime {
0% {
transform: translate(-20vw);
}
100% {
transform: translate(0);
}
}
.sign_in_eg {
height: 100vh;
width: 20vw;
background: red;
}
.img_eg {
height: 100vh;
width: 100vw;
background: blue;
}
<div class="parent_container">
<div class="sign_in_eg">This is for signin</div>
<div class="img_eg">This is for image</div>
</div>
I have a DIV with "width: 100%", and after some time it moves to a different width (for example "width: 50%") with a nice transition. I want that the part which is going to decrease to get a different color. How do I do it?
.container {
width: 80%;
height: 50px;
}
.bar {
background-color: red;
width: 100%;
height: 100%;
transition-duration: 1s;
}
<div class="container">
<div class="bar"></div>
</div>
You can simply put another bar exactly behind this bar. Set it's z-index to 1. And your current bar's z-index to a higher number.
The bar that is in the back, has a black color like you wanted.
Now when the red bar decrease it's width, the one in the back becomes visible.
Here you go, the most basic working example.
(Try hovering the bar and see it moving)
By simply overlaying a pseudo-element over the static .bar element, with position:absolute, it is places above the bar and has dynamic width which you should change.
.container {
width: 80%;
height: 50px;
}
/* static background bar */
.bar {
--progress: 80%; /* css variable */
position: relative;
background-color: salmon;
width: 100%;
height: 100%;
}
/* This is the part which moves: */
.bar::before{
content: '';
background-color: darkred;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
width: var(--progress);
transition: 1s;
}
.bar:hover {
--progress: 20%;
}
<div class="container">
<div class="bar"></div>
</div>
This solution uses a linear-gradient where I animate the background-size. I placed a fully black gradient on the .container, and a red one on the .bar, where I put a transition: background-size 1s on the black .container.
By using javascript to change a CSS variable, I can get the bar to animate.
Added a range to show-case the result.
Do note that it's always better to specify what attribute to animate with transiation, because otherwise the browser loops through all animatable properies, which can create janky animations.
let rangeInput = document.querySelector('input[type="range"');
let containerDiv = document.getElementById("container");
if (rangeInput) {
rangeInput.addEventListener('change', (event) => {
let newValue = event.target.value;
containerDiv.style.setProperty('--bar-width', `${newValue}%`);
});
}
input[type="range"] {
width: 80%;
margin-top: 1rem;
}
#container {
--bar-width: 100%;
width: 80%;
height: 50px;
background: linear-gradient(black, black);
transition: background-size 1s;
}
/* added "div" to obtain a higher specificity, to override the default background properties. */
div#container,
div.bar
{
background-repeat: no-repeat;
background-size: var(--bar-width);
}
.bar {
background: linear-gradient(red, red);
width: 100%;
height: 100%;
}
<div id="container">
<div class="bar"></div>
</div>
<input type="range" value="100" />
I want to make divs which got backgrounds that have this 3d-effect while scrolling, that one can achieve with translateZ. In the end it should look like cutouts or windows and through them you can see the (background-)images.
edit: So, if you scroll through the page you can see those boxes/cutouts but the images inside them are moving slower while scrolling to create the effect that they are further away. end of edit
What I have in mind is to have one div for the cutout and then another div inside it for the background. So, i set it up and it didn't work. It turns out that the overflow: hidden; of the outer div somehow blocks the transform: translateZ(-5px) scale(1.05); of its child.
Here is what I have got so far:
body {
perspective: 100px;
transform-style: preserve-3d;
overflow-x: hidden;
overflow-y: scroll;
}
#artwork, #photos {
width: 800px;
padding: 0 50px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.pic {
/*position: relative;*/
width: 200px;
height: 100px;
display: inline-block;
background: #aaa;
border-radius: 10px;
box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}
#artwork > * {
overflow: hidden;
}
.pic div {
position: absolute;
width: 200px;
height: 110px;
background: #660; /*couldn't put an image here*/
background-size: cover;
transform: translateZ(-5px) scale(1.05);
}
<section id="artwork">
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
</section>
P.S.: I don't want to achieve the effect via JavaScript because it's not working smoothly on most computers.
edit n°2: my approaches so far:
- making extra tick borders to cover overlapping parts of the image divs; instead of using overflow: hidden >> parts are sometimes still overlapping on some screen sizes & it takes a lot of space
- creating a clip-path to use as overflow: hidden >> clip-paths also break the translateZ
- playing around with display and position on both outer and inner div >> only solutions without cutout
- Ztranslating the parent of the outer div further away and then bringing the outer div close again >> still blocked by the overflow: hidden;
I found a workaround, although it's a compromise because the border radius isn't working. I added thick borders in the background color to the outer divs and set the z-index of the inner divs to something negative.
body {
height: 200px;
perspective: 100px;
transform-style: preserve-3d;
overflow-x: hidden;
overflow-y: scroll;
}
#artwork {
width: 800px
padding: 0 50px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.pic {
width: 200px;
height: 100px;
margin: -40px;
display: inline-block;
background: transparent;
border: 40px solid hsl(30, 50%, 90%);
box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}
.pic div {
position: absolute;
width: 200px;
height: 110px;
background: linear-gradient(135deg, rgba(240,183,161,1) 0%,rgba(140,51,16,1) 50%,rgba(117,34,1,1) 51%,rgba(191,110,78,1) 100%);
transform: translateZ(-5px) scale(1.05) translateY(-1vw);
z-index: -20;
}
#artwork div:nth-child(2) div, #photos div:nth-child(2) div {transform: translateZ(-5px) scale(1.05) translateX(-1.5vw) translateY(-1vw);}
#artwork div:nth-child(4) div, #photos div:nth-child(4) div {transform: translateZ(-5px) scale(1.05) translateX(1.5vw) translateY(-1vw);}
<br><br><br><br><br><br><br>
<section id="artwork">
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
</section>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
that code snippet doesn't work here for some reason. For me however it works in the browser. It would be nice if someone could suggest another possible solution as this one works with only some screen sizes.
I am trying to position two DIVs over each other so that when the pointer hovers over the picture the top one fades to show the one underneath. I did this here: http://quaystreet.chrisloughnane.net/
I want make it responsive so the pictures would scale to the horizontal width of the mobile device. Which is no problem with one picture but as soon as I try to re-position the underneath DIV it breaks.
http://jsfiddle.net/chrisloughnane/f2NdQ/4/
Is it possible with just CSS to do what I want?
<div id='old'><img src="http://quaystreet.chrisloughnane.net/images/quay-street-old.jpg"/></div>
<div id='new'><img src="http://quaystreet.chrisloughnane.net/images/quay-street-new.jpg"/></div>
img {
max-width: 100%;
display: block;
margin: auto;
}
Here we go,
Live Example
CSS:
.images {
width: 100%;
position: relative;
max-width: 354px;
margin: 0 auto;
}
.images img {
position: absolute;
top: 0;
width: 100%;
max-width: 354px;
}
JavaScript:
$(document).ready(function() {
$('.images').on('mouseenter', function(){
$('.images .old').fadeOut(1000);
}).on('mouseleave', function(){
$('.images .old').fadeIn(1000);
});
});
HTML:
<div class="images">
<img class="new" src="http://quaystreet.chrisloughnane.net/images/quay-street-new.jpg">
<img class="old" src="http://quaystreet.chrisloughnane.net/images/quay-street-old.jpg">
</div>
Some things to you know:
To make each div in front of each other I am using position absolute.
I change the whole thing you did to make the div fadeOut, I think that way is more cleaner
I change your HTML to use the absolute position.
Your img will be width 100% and max-width 354px can be any value just need to be the maximum width your img will use. So when is less then 354px he will use the whole div with 100%.
Edit:
If you don't care about browser support you can use CSS3 transitions, beware no IE<10.
Here is the answer with transition
JavaScript it's not really necessary. You can achieve the same behaviour with a smooth CSS3 transition
.images {
position: relative;
margin: 0 auto;
}
.images img {
position: absolute;
top: 0;
left: 0;
width: 100%;
max-width: 354px;
-webkit-transition: opacity .8s linear 0s;
transition: opacity .8s linear 0s;
}
.images img:first-child {
z-index: 2;
}
.images img:first-child:hover {
opacity: 0;
}
example fiddle : http://jsfiddle.net/uNkY5/1/
Setup
I have three divs using CSS3 translations in all directions within a container div that is itself within an outer, fullscreen div. The outermost div, the full screen one, has perspective set on it.
HTML
<div class='outer'>
<div class='container ofhidden'>
<div class='item' id='item1'></div>
<div class='item' id='item2'></div>
<div class='item' id='item3'></div>
</div>
</div>
CSS
.outer {
perspective: 1000;
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
}
.outer .container {
background-color: grey;
width: 130%;
height: 100%;
padding: 1em;
}
.outer .container.ofhidden {
overflow: hidden;
}
.outer .container .item {
border: 1px solid black;
width: 50px;
height: 50px;
}
.outer .container .item#item1 {
background-color: green;
transform: translate3d(10px, 10px, -10px);
}
.outer .container .item#item2 {
background-color: goldenrod;
transform: translate3d(10px, 10px, 0);
}
.outer .container .item#item3 {
background-color: red;
transform: translate3d(10px, 10px, 10px);
}
Problem
The div that contains the translated elements has overflow: hidden; set on it which disables or ignores the translation in the Z direction while not effecting the other directions.
Demo
Please see this pen http://codepen.io/aaron/pen/Ihrxj for the code and a button which toggles overflow: hidden; to demonstrate the effect.
For those not familiar with HAML, SCSS/Compass, or CoffeeScript, you can click on the name of the preprocessor next to HTML, CSS, and JS to see the generated code in the codepen.
I don't know why this is happening, but i can suggest a couple of workarounds.
An obvious solution is to set overflow: hidden; (if you really need it) on items (either with .item or .container > *, instead of applying it to the container.
Another option is to position items absolutely. It's not very handy but it might work out for your layout (you can position items absolutely relatively to the container).
In both cases transform3d won't be disabled/ignored.