I have a series of images on-screen in bootstrap 3 panels (3 per row for large screens).
When you click on an image I have it set up so that it applies a CSS class which does a 'scale(2)' on the image, this all works fine, but I want those images to be visible and scale themselves on screen.
Images in column 1 end up slightly off-screen to the left, Images in column 3 end up slightly off-screen to the right, Images in column 2 are for the most part fine.
Ideally I would like them to scale into the centre of the viewport itself, or at least just not render off-screen at all.
CSS:
.zoom {
-webkit-transition: all 0.35s ease-in-out;
-moz-transition: all 0.35s ease-in-out;
transition: all 0.35s ease-in-out;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in;
}
.zoom-click {
-ms-transform: scale(2);
-moz-transform: scale(2);
-webkit-transform: scale(2);
-o-transform: scale(2);
transform: scale(2);
position:relative;
z-index:100;
border: 2px solid DarkRed;
}
Upon clicking on the image it adds/removes the 'zoom-click' class.
I have tried using 'translate' along with the 'scale' however it is relative to the image itself, have also tried using 'transform-origin'.
**Update: ** Have created a jsfiddle showing how it is at present (minus the knockoutjs code which actually creates each of the 'main-image-panel' panels.
https://jsfiddle.net/tczh1sxq/2/
Figured it out. I always seem to have difficulty at times with the more complex CSS.
Anyway, fixed it by doing:
#images > div .zoom-click { transform-origin: top; }
#images > div:nth-child(3n+0) .zoom-click { transform-origin: top right; }
#images > div:nth-child(3n+1) .zoom-click { transform-origin: top left; }
Be nice if I could get it to actually go into the centre of the viewport, but this will suffice, looks much neater now that it isn't off-screen on the edges.
this might help,
.zoom-click
{
position: absolute;
height: 50%;
width: 50%;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
}
You can use any height/ width you want. If the image is contained within any positioned element, you can use position: fixed and it will still work
Just an idea tried to resolve your issue. I used different tranform-origin based on child element index value as like nth-child,
$('.child').click(function(){
var index = $(this).index()+1;
if((index%3)==1){
$(this).find('img').css({
'transform': 'scale(2)',
'transform-origin': 'top left'
});
}
else if((index%3)==2){
$(this).find('img').css({
'transform': 'scale(2)',
'transform-origin': 'top'
});
}
else if((index%3)==0){
$(this).find('img').css({
'transform': 'scale(2)',
'transform-origin': 'top right'
});
}
});
Find this fiddler for reference.
Related
I am creating a website for a project and got stuck with an issue.
I was trying to implement the hover feature, where when I hover over the image it gets zoomed in. That part works nicely, however, I was having an issue when I hover over the last book in the first row. When I hover over that, the entire screen becomes glitchy. This feature is not working as I hoped, i.e. smooth and good to work with. I have attached the image and the code I have.
Thanks for any help!
.books img{
width:200px;
height:300px;
}
.books img:hover {
position: relative;
left: 45px;
width: 300px;
height: 400px;
display: block;
}
I found some code online using -mox-transform and -webkit-transform, however, I have never worked with that before. This seemed complex for me. Any suggestions if I should learn how that works instead of perfecting the above code?
By increasing the width and height on hover the surrounding layout must adapt to that size change. The browser must move the surrounding elements to provide the space for the larger element, that is why it is glitchy.
If you want to do it properly, you will probably have to use transform, as you mentioned.
For your use case it should not be hard. Try this:
.books img {
width: 200px;
height: 300px;
transition: transform 200ms; /* optional transition with 200ms duration */
}
.books img:hover {
transform: scale(1.1); /* scale to 110% */
}
All you need to use is scale property to scale the image. Change your code to this
.books img:hover {
transform: scale(1.5);
}
This should do what you are looking for.
Use transform CSS Property with scale() which is used to increase or decrease the size of an element
.books img:hover {
transform: scale(1.2);
}
CSS transform scale() function appears to have a bug on Safari when it's used on elements with a border.
I'm trying to zoom an image on mouse over using transform: scale() function but if the image has a border then it gets pixelated when scaled.
Here is a sample of the same element with the same CSS rules applied (except the border):
Code example: https://jsfiddle.net/m6g4kw30/
div {
text-align: center;
}
img {
height: 100px;
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-o-transition: all .3s ease;
-ms-transition: all .3s ease;
transition: all .3s ease;
border: 1px solid #000;
margin: 20px;
}
img.noborder {
border: none;
}
img:hover {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform: translateZ(0) scale(5);
-moz-transform: scale(5);
-ms-transform: scale(5);
-o-transform: translateZ(0) scale(5);
transform: translateZ(0) scale(5);
}
<div>
<img src="https://via.placeholder.com/1000.png" alt="">
<img src="https://via.placeholder.com/1000.png" class="noborder" alt="">
</div>
CSS transform scale() function appears to have a bug on Safari when it's used on elements with a border.
You can say that again! Unfortunately, the reported bug(s) for this (and similar) issues go back many years, with the following bug referenced in most:
https://bugs.webkit.org/show_bug.cgi?id=27684 (Opened in 07/2009)
If you didn't catch the date, it's a 10 year old bug that's still causing developers issues today! YIKES.
Basically, the issue comes down to Safari rasterizing the layer. On transform/scale, it resizes the layer, however it does not re-render the rasterized layer. In your use-case, the rasterized image is scaled up, but the text/image is blurry.
As for a workaround/fix? There are a couple ways you can "address" this:
1) Force a re-render
A quick/easy fix is to force Safari to re-render your layer when you transform. One way this can be achieved is by applying a CSS property which you then change after transforming (some people have success changing a background-color, for example). For your specific use case, I had luck with the following combination:
img {
outline: 1px solid #000;
border: none;
}
img:hover {
outline: none;
border: 1px solid #000;
}
By toggling those specific values, I was able to force Safari to re-render the rasterized layer, thus rendering a sharp image (similar to the non-border example). Here's a JSFiddle with the full code example: https://jsfiddle.net/gc56brfh/
2) Scale down, then up
Another workaround, documented here, is to set the element's initial size to the "scaled up" dimensions, and then scale down the element until you're ready to scale it up. That way, the element is rasterized to the correct dimensions.
CSS wise, that may look like:
img {
-webkit-transform: translateZ(0) scale(0.2);
height: 250px;
}
img:hover {
-webkit-transform: translateZ(0) scale(1);
}
In the above, we've set the initial size of the img to 250px (this is based on your original css, with images being 50px and then scaled up 5). We then scale down the image by 0.2, resulting in 50px. On hover, we then scale back up to 250px by setting scale(1).
Here's an updated JSFiddle: https://jsfiddle.net/df2zqgnx/
One thing to note is that other CSS properties might need to be updated with this workaround. For example, you'll notice in the fiddle I also needed to update the border from 1px to 5px to compensate for the scaling down.
Anyway, hope this was helpful and one of the solutions works for you!
I'm very new to HTML and CSS but I've strung together some code that makes my images enlarge a little bit when my mouse hovers over them. However, the images sometimes don't enlarge over each other, some stay behind others because they are positioned closely together. Does anyone know how to make them ignore the other images when they enlarge?
Here's my code:
img.one {
position: absolute;
cursor: pointer;
top: 10px;
left: 10px;
transition: all .2s ease-in-out;
}
img.one:hover {
transform: scale(1.1);
}
Use the z-index property to control which elements are in front of others.
img.one:hover {
transform: scale(1.1);
z-index: 1;
}
I have a bootstrap template which include a navigation bar with 3 links. Each link point to an anchor.
Each anchor is a SECTION with height set to 100%. The scrollbar is hidden so the only way to navigate to the next section is by using the navigation bar.
I want to add an animation while the anchor is change.
I setup my template and the animation but I don't understand why my DIVS goes offset instead of scrolling as expected.
My JSFiddle is https://jsfiddle.net/raffaeu/qu4skwf4/
I set the transitions as following:
#home:target{
-webkit-transform: translateY( 0px);
transform: translateY( 0px );
}
#about:target{
-webkit-transform: translateY(-100%);
transform: translateY(-100%);
}
#contact:target{
-webkit-transform: translateY(-200%);
transform: translateY(-200%);
}
And this is how I set the animation for each section
section {
width: 100%;
height: 100%;
z-index:0;
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-transition: -webkit-transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
I belive that in this case CSS translate is unnecessary and even plain wrong approach. Scrollbar is invented for a reason, and you should not take it away from page visitors. Also, think about mobile users.
I suggest better using jQuery.offset function and add animation, like this:
function scrollToAnchor(aid){
var aTag = $("a[name='"+ aid +"']");
$('html,body').animate({scrollTop: aTag.offset().top},'slow');
}
scrollToAnchor('id3');
I am trying to do a simple image fade on rollover - works fine and smooth in Chrome, but Firefox is a bit jumpy. I've tried doing the backface-visibility trick on the container, but still no luck.
Anyone have any ideas?
JSFiddle
HTML
<div class="link-box large">
<div class="image">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRStwH3maKRqLU8lLOo1XbO6uZIKHRyf2PGv66H6ol5mB0kS_0r" alt="">
</div>
</div>
CSS
.link-box .image img { transition: all .2s ease-out; width:200px; }
.link-box.large { position: relative;}
.link-box.large:hover .image img { opacity: .65; }
My best guess is that setting the width of the image to 200px and leaving the height unspecified is causing the browser to calculate the height of the image. If the height calculates to a nice whole number it isn't an issue. If the height calculates to a decimal it may be the cause of the problem.
In this case the natural dimensions of the image are 275px by 183px.
By changing the width of the image to 200px you are shrinking the image to 72.727272...% of its natural size.
275/200 = 0.727272... Or if you prefer fractions: 275(8/11) = 200
Now running the same equation on the height yields:
183(8/11) = 133.090909...
It looks like, under the normal run of things, the partial pixels are cropped, but during the transition the partial pixels aren't being cropped, and the image is warped slightly to show the partial pixels within the same height.
Cropped down to 133px:
Not cropped and slightly warped:
Now that we have a good hypothesis on what's causing the problem, on to the solutions:
You can hard code the height of the image:
Working Example
.link-box .image img {
transition: all .2s ease-out;
width:200px;
height: 133px; /* manually set the height */
}
Or if you would rather not hard code the height, you can also fix the issue with an anti-alias hack, just add a box-shadow.
Working Example
.link-box.large:hover .image img {
opacity: .65;
box-shadow: 0 0 0 #000; /* add a non-visible box-shadow */
}
Or if you're concerned about the cross-browser compatibility of using a box-shadow, you can also use a transparent border:
Working Example
.link-box .image img {
transition: all .2s ease-out;
width:200px;
border: 1px solid transparent; /* add transparent border */
}
Works good on my Firefox.
Anyway you can try to add some special attributes that will prepare the browser for the transition and actually render the element with possible transformation in mind.
Such an attribute is transform: translate3d(0,0,0);
Like this :
.link-box .image img {
transition: all .2s ease-out;
width:200px;
transform: translate3d(0,0,0);
}
.link-box.large { position: relative;}
.link-box.large:hover .image img { opacity: .65; }