I have a large element that has multiple animated (rotating) images, and you can zoom in and out on the entire div (which changes its scale transform). However, if an image element is created while the div is zoomed out, when I zoom back in I can see that the image is very blurry, as if it the image was downscaled when the element was created. A possible workaround would be to hide & show the image every time I zoom, but that doesn't sound like the best solution.
Here's a snippet demonstrating the issue (fiddle). Click on the first link to get a blurred image (sometimes only breaks on the second click), and on the second link to get a good image.
$(".try-1").click(function() {
$(".image").remove();
$(".pos").css("transform", "scale(0.4)").append("<div class=\"image\"></div>");
setTimeout(() => {
$(".pos").css("transform", "scale(1.4)");
}, 500)
});
$(".try-2").click(function() {
$(".image").remove();
$(".pos").css("transform", "scale(1.4)").append("<div class=\"image\"></div>");
});
.clicky {
color: #00f;
cursor: pointer;
}
.clicky:hover {
text-decoration: underline;
}
.div {
position: relative;
width: 500px;
height: 500px;
background: #000;
}
.pos {
position: absolute;
left: 250px;
top: 250px;
}
#keyframes rotating-cw {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.image {
position: absolute;
left: -150px;
top: -150px;
width: 300px;
height: 300px;
background: url(http://i.imgur.com/grJ6I3k.png);
background-size: 300px 300px;
animation: rotating-cw 30s linear infinite;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="clicky try-1">Create & zoom in</span> | <span class="clicky try-2">Zoom in & create</span>
<div class="div">
<div class="pos">
</div>
</div>
use this:
.pos {
-webkit-perspective: 1000;
position: absolute;
left: 250px;
top: 250px;
}
This can be solved using requestAnimationFrame but a simpler and more straightforward solution is to tell the browser to again initialize the image's container
$(".try-1").click(function() {
$(".image").remove();
$(".pos").css("transform", "scale(0.4)").append("<div class=\"image\"></div>");
setTimeout(() => {
$(".pos").css("transform", "scale(1.4)");
// Here, after we scale up the element again append
// the .image element but first remove it
$(".image").remove();
$(".pos").append("<div class=\"image\"></div>");
}, 500)
});
JsFiddle
Related
I have a drawer menu that appears on screen after clicking a button. The transition is a little laggy using absolute positioning so I went with using translate3d. The menu has two widths. One that's 100% of the view for mobile and 395px for viewports 600px and up. One quirk I'm noticing is that if I were to resize my screen, the menu will subtly appear. Is there a way to get the menu to completely stay off-screen when this happens?
Note: To see this, expand the snipped to full-screen and horizontally resize to 600px or lower. You should see see the div appear and go back off-screen.
$('button').on('click', function() {
$('#drawer').toggleClass('active');
});
html,
body {
height: 100%;
margin: 0;
}
#drawer {
width: 100%;
height: 100%;
background-color: grey;
transition: transform .5s ease-in;
transform: translate3d(-100%, 0, 0);
}
#drawer.active {
transform: translate3d(0, 0, 0);
}
#media (min-width: 600px) {
#drawer {
transform: translate3d(-395px, 0, 0);
width: 395px;
}
}
button {
position: absolute;
top: 10px;
left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drawer"></div>
<button>Toggle Drawer</button>
The problem: A transition is set on the drawer's transform property. When it hits the designated media query, the drawer transitions to it's new x coordinate.
The solution: Instead of putting the responsibility of placement solely on transform, use absolute positioning and initially offset the drawer to its' negative width. In this case it would be 395px. On the active state, the transform3d property would be the width of the drawer to bring it back into the visible part of the window.
$('button').on('click', function() {
$('#drawer').toggleClass('active');
});
html,
body {
height: 100%;
margin: 0;
}
#drawer {
width: 100%;
height: 100%;
position: absolute;
left: -100%;
background-color: grey;
transition: transform .5s ease-in;
transform: translate3d(0,0,0);
}
#drawer.active {
transform: translate3d(100%, 0, 0);
}
#media (min-width: 600px) {
#drawer {
left: -395px;
width: 395px;
}
#drawer.active {
transform: translate3d(395px, 0, 0);
}
}
button {
position: absolute;
top: 10px;
left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drawer"></div>
<button>Toggle Drawer</button>
on my home page I have a grid block with 6 images on it
On hover, it becomes more transparent thanks to CSS (opacity: 0.6)
I also would like that when I hover on the button at the center of the image, the image itself keeps being transparent
Since it's not the case here
So I have applied some code here, but I couldn't figure why it doesn't work
.flexItem.grid_sections .button:hover ~ .grid_sections img {
opacity: 0.6;
}
Those elements appear on my homepage, 5th section
URL: https://www.tresor-ethnique.com/
Any idea?
Let me know, and thank you in advance :)
Pascal
Try
div {
height: 260px;
width: 260px;
position: relative;
}
div > img {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
opacity: 0.6;
}
div > button {
position: absolute;
z-index: 2;
top: 45%;
left: 30%;
width: 80px;
height: 45px;
}
div > button:hover + img {
opacity: 1;
}
<div>
<button>Button</button>
<img src="https://via.placeholder.com/260x260">
</div>
NOTE: you must put the button tag before img tag
I have a css transition that is triggered by changing an attribute with JQuery/JS.
It works nicely, except in internet explorer (11).
I have no idea what's going on here, any ideas?
Edit: the problem seems to be caused by using viewport units. It works fine when using any other type of unit. The second snippet shows a working example.
$('#click').click(function() {
var data_test = $('#container').attr('data-test');
if(data_test == 'one') $('#container').attr('data-test', 'two');
else $('#container').attr('data-test', 'one');
});
#container {
position: relative;
width: 100%; height: 100px;
}
#container > div {
position: absolute;
right: 1vw;
font-size: 1em;
top: 0.1em;
transition: all 1s;
}
#container[data-test="one"] > div {
transform: translate(-8vw, 15vh);
font-size: 1.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" data-test="one"><div>some text</div></div>
<div id="click">click</div>
$('#click').click(function() {
var data_test = $('#container').attr('data-test');
if(data_test == 'one') $('#container').attr('data-test', 'two');
else $('#container').attr('data-test', 'one');
});
#container {
position: relative;
width: 100%; height: 100px;
}
#container > div {
position: absolute;
right: 1vw;
font-size: 1em;
top: 0.1em;
transition: all 1s;
}
#container[data-test="one"] > div {
transform: translate(-4em, 4em);
font-size: 1.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" data-test="one"><div>some text</div></div>
<div id="click">click</div>
Transitioning shouldn’t be done on top, right, bottom or left anymore. For best performance use transform: translateY(value); or transform: translateX(value);. Remove the top props and transform those elements.
Repaints are probably messing it up. Let me know if it works ;-)
So apparently you need to set transform-origin in Internet Explorer. See the snippet. Note that you also need to transition transform-origin.
Thanks to cewn for helping me on my way to find the answer.
$('#click').click(function() {
var data_test = $('#container').attr('data-test');
if(data_test == 'one') $('#container').attr('data-test', 'two');
else $('#container').attr('data-test', 'one');
});
#container {
position: relative;
width: 100%; height: 100px;
}
#container > div {
position: absolute;
right: 1vw;
font-size: 1em;
top: 0.1em;
transform-origin: -8vw 15vh;
transform: translate(0vw, 0vh);
transition: all 1s;
}
#container[data-test="one"] > div {
transform-origin: 0vw 0vh;
transform: translate(-8vw, 15vh);
font-size: 1.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" data-test="one"><div>some text</div></div>
<div id="click">click</div>
I ran into a similar problem when experimenting with a new navigation menu that used transform to rotate a DIV. Some of DIVs expand as they rotate, so I was already setting transform-origin to ensure that they rotate about the original centre. I'm using viewport units for sizing. It worked in every browser apart from Internet Explorer.
I know it's a "bodge", but, having read here that IE doesn't like viewport units, a quick fix for me was to change transform-origin: 5vw 5vw to transform-origin: calc(5vw) calc(5vw) - the page now looks the same in IE as it does in other browsers.
I am trying to set up am image inside a main div where hovering over the div will make the attached image scale up over 2 seconds. Only the div itself (border) scales, not the attached image itself. Attempting to scale the image alone has no action as of this writing. This is being done in Rails 5.1.2. What am I missing?
views/community/index.html.erb:
<div class="scene">
<div id="container1" class="image-div">
<%= image_tag("hbehance.png", :id =>"first-image", :alt => "first symbol") %>
</div>
</div>
stylesheets/community.css.scss:
.scene {
position: relative;
height: 35rem;
margin: 1rem;
width: 95%;
left: 0;
top: 0;
background-image: asset_url("cityscape.jpeg");
background-size: cover;
}
.image-div{
position: absolute;
bottom: 10%;
width: 60px;
height: 60px;
border: 5px solid red;
}
img {
position: absolute;
width: 100%;
transition: transform all 2s;
}
.image-div:hover {
transform: scale(2);
}
Figured it out!
The image was nested inside the div, but needed to be appended in order to respond in tandem:
javascript/community.js:
document.addEventListener('DOMContentLoaded', function(){
firstDiv = document.getElementById('container1');
firstImage = document.getElementById('first-image');
firstDiv.append(firstImage);
function testJS(){
firstDiv.style.left = "50%";
}
testJS();//tests that JS file connects properly when first setup
})
Is there any way to make semi-transparent overlapping elements, from which only higher z-index will be visible? I would like the images to be transparent to the background, but not to the other pictures. Here is fiddle.
body {
background: white;
}
section {
height: 400px;
position: relative;
perspective: 500px;
}
img {
height: 300px;
left: 50%;
margin: -100px;
position: absolute;
top: 40%;
transform: rotateY(-30deg);
width: 200px;
}
img:nth-child(1) {
left: 30%;
opacity: 0.8;
z-index: 3;
}
img:nth-child(2) {
left: 45%;
opacity: 0.4;
z-index: 2;
}
img:nth-child(3) {
left: 60%;
opacity: 0.2;
z-index: 1;
}
<section>
<img src="https://media4.s-nbcnews.com/j/newscms/2016_36/1685951/ss-160826-twip-05_8cf6d4cb83758449fd400c7c3d71aa1f.nbcnews-ux-2880-1000.jpg">
<img src="http://toprozdily.cz/wp-content/uploads/2015/04/slon-africky.jpg">
<img src="http://img.huffingtonpost.com/asset/,scalefit_950_800_noupscale/55fc14631c00004800082775.jpeg">
</section>
So what you're going to need to do is put the images each in their own div container and set the div background-color to white. That way you see the white background through the semi-opaque images and not the image underneath.
I edited your fiddle to give you the functionality you're looking for. Hope it helps!
There isn't a way to make an element be transparent to one element but opaque to another.
However, you might be able to simulate the transparency by tinting the images instead, either by positioning a partially-transparent div of that color over each image, or with CSS filters:
https://www.w3schools.com/cssref/css3_pr_filter.asp