Zooming-in the image centered around the cursor with CSS - css

I have a map image, and I want to zoom in/out when I click on it. This code below zooms it, but I want to zoom-in the image centered around the location of the cursor and make horizontal-scroll appear. How can I do it with only CSS?
CSS
input[type=checkbox]{
display: none;
}
.container img{
transition: transform 0.25s ease;
cursor: zoom-in;
}
input[type=checkbox]:checked ~ label > img{
-webkit-transform: scale(2);
transform: scale(2);
cursor: zoom-out;
}
HTML
<div class="container"><input id="zoomCheck" type="checkbox" />
<label for="zoomCheck">
<img src="map.jpg" />
</label></div>

I created you the logic you can use. Just add the other functionality.
Basically, this is what you want.
Fiddle: https://jsfiddle.net/zpobnetf/11/
How can you achieve it?
Get position of click (clientX, clienY)
Clone the image into a div with background image (src of the image clicked)
Position them depending on the position that was clicked on.
As you can see on my example. I subtract clientX and clientY by 75. It's because the box that I created has a size of 150x150. I just divide it by 2. So, I can position the #box at the center.
Hope you get it. Cheers! You can do it. Just believe!
let mapa = document.getElementById('map'),
box = document.getElementById('box');
mapa.addEventListener('click', (e) => {
let xPos = (e.clientX - 75),
yPos = (e.clientY - 75);
box.style.display = 'initial';
box.style.top = `${yPos}px`;
box.style.left = `${xPos}px`;
box.style.backgroundPosition = `-${xPos}px -${yPos}px`;
});
#box {
height: 150px;
width: 150px;
background: rgba(255,255,255,0.8);
background-image: url('https://www.gstatic.com/images/branding/googlelogo/2x/googlelogo_color_284x96dp.png');
background-repeat: no-repeat;
transform: scale(1.4);
position: absolute;
display: none;
}
<img id="map" src="https://www.gstatic.com/images/branding/googlelogo/2x/googlelogo_color_284x96dp.png">
<div id="box"></div>

Related

CSS center image animation in the middle of the page

I have the following code that transitions an image from the bottom to the top, but I need this to center. On my colleagues screen it is centered, but on mine it is more at the top. Is there a way to ensure it is centered on all screens? (without breaking the rest of my CSS lol)
JS:
const showAlerts = () => {
getElements().forEach((alert) => {
focus-alert.style.display = "";
focus-alert.style.bottom = "25%"; // <--- *This is what does the transition to the 'center'*
});
};
HTML
<div class="mobile-wrapper">
<div id="mobile" class="focus-alert">
<img src="assets/images/mobile-moments-away-img.png">
<img id="mobile-close-btn" class="mobile-close-btn" src="assets/images/mobile-close-button-img.png" onclick="handleClose(this)">
<img id="mobile-continue-btn" class="mobile-continue-btn" src="assets/images/mobile-continue-now-img.png" onclick="handleGetQuotesClick(this)">
</div>
</div>
CSS:
.mobile-wrapper {
display: flex;
align-items: center;
justify-content: center;
/*height: 100vh;*/
}
#mobile {
position: fixed;
z-index: 9999;
transition: all 1s ease;
}
If I change focus-alert.style.bottom = 25% to 20% that centers on my screen but obviously wont for his. So just wondering how to make it centered in the middle?
Hello can you try margin:50% auto 50% auto; on image style, add it in your script that will help you to center image on middle of screen

Zoom in and out on mouse click with CSS

I want to zoom image with only CSS. The code below zooms the image when the left button of the mouse is kept pressed but I want to zoom in and out with a mouse click. How can I achieve that?
.container img {
transition: transform 0.25s ease;
cursor: zoom-in;
}
.container img:active {
-webkit-transform: scale(2);
transform: scale(2);
cursor: zoom-out;
}
Let's use a trick here, an input checkbox:
input[type=checkbox] {
display: none;
}
.container img {
margin: 100px;
transition: transform 0.25s ease;
cursor: zoom-in;
}
input[type=checkbox]:checked ~ label > img {
transform: scale(2);
cursor: zoom-out;
}
<div class="container">
<input type="checkbox" id="zoomCheck">
<label for="zoomCheck">
<img src="https://via.placeholder.com/200">
</label>
</div>
Building on #Nhan answer: https://stackoverflow.com/a/39859268/661872
Shorter, scoped and does not require tracking ids for multiple elements.
.click-zoom input[type=checkbox] {
display: none
}
.click-zoom img {
margin: 100px;
transition: transform 0.25s ease;
cursor: zoom-in
}
.click-zoom input[type=checkbox]:checked~img {
transform: scale(2);
cursor: zoom-out
}
<div class="click-zoom">
<label>
<input type="checkbox">
<img src="https://via.placeholder.com/200">
</label>
</div>
<div class="click-zoom">
<label>
<input type="checkbox">
<img src="https://via.placeholder.com/200">
</label>
</div>
4 Ways to Add Click Events with Only CSS Pseudo-Selectors
Note: I'll be using the word target when referring to the element we want to manipulate and trigger as the element we are using to manipulate target.
:checked
Use checkboxes or radios and :checked to determine or cause a target's state and/or to take action.
Trigger
<label>
<input type="checkbox">
<!--or-->
<input type="radio">
Conditions
Requires that the target must be:
A sibling that follows the trigger or...
...a descendant of the trigger.
Note
Hide the actual <checkbox> with display:none
Ensure that the <checkbox> has an id and that the <label> has a for attribute with a value matching the id of the <checkbox>
This is dependant upon the target being a sibling that follows the trigger or the target as a descendant. Therefore be aware that you'll most likely use these selector combinators: ~, +, >.
HTML
<label for='chx'>CHX</label>
<input id='chx' type="checkbox">
<div>TARGET</div>
CSS
#chx:checked + div {...
:target
Use an <a>nchor and apply the :target pseudo-selector on the target element.
Trigger
Conditions
Assign an id to the target.
Assign that same id to the <a> href attribute preceding with a hash #
HTML
<a href='#target'>A</a>
<div id='target'>TARGET</div>
CSS
#target:target {...
:focus
The trigger element must be either an <input> type or have the attribute tabindex in order to use :focus.
Trigger
<div tabindex='0'>ANY INPUT OR USE TABINDEX</div>
Conditions
Target must a sibling that is located after the trigger or *target must be a descendant of the trigger.
State or effect will persist until user clicks elsewhere thereafter a blur or unfocus event will occur.
HTML
<nav tabindex='0'>
<a href='#/'>TARGET</a>
<a href='#/'>TARGET</a>
<a href='#/'>TARGET</a>
</nav>
CSS
nav:focus ~ a {...
:active
This is a hack that cleverly exploits the transition-delay property in order to actually have a persistent state achieved with no script.
Trigger
<a href='#/'>A</a>
Conditions
Target must a sibling that is located after the trigger or *target must be a descendant of the trigger.
There must be a transition assigned to the target twice.
The first one to represent the persistent state.
The second one to represent the normal state.
HTML
A
<div class='target'>TARGET</div>
CSS
.target {
opacity: 1;
transition: all 0s 9999999s;
}
a:active ~ .target {
opacity: 0;
transition: all 0s;
}
Wacked looking, right? I'll try to explain it, but you're better off reading this article.
Under normal circumstances, if your trigger had the :active pseudo-selector, we are able to manipulate the target upon keydown. That means our active state is actually active as long as you keep your finger on the button...that's crappy and useless, I mean what are you expected to do to make .active to be useful? Maybe a paperweight and some rubber bands to keep a steady and persistent pressure on the button?
We will leave .active the way it is: lame and useless. Instead:
Make a ruleset for target under normal circumstances. In the example above it's opacity:1.
Next we add a transition: ...ok then... all which works, next is 0s ...ok so this transition isn't going to be seen it's duration is 0 seconds, and finally... 9999999s ...116 days delay?
We'll come back to that, we will continue onto the next rulesets...
These rulesets declare what happens to target under the influence of trigger:active. As you can see that it just does what it normally does, which is onkeydown target will become invisible in 0 seconds. Now once the user keys up, target is visible again...no *target's * new state of opacity:0 is persistent! No paperweight, technology has come a long way.
The target is still actually going to revert back to it's normal state, because :active is too lazy and feeble to work without rubber bands and paperweights. The persistent state is perceived and not real because target is still leaving the state brought on by :active which will be about 116 days before that will happen. ;)
This Snippet features the 4 ways previously mentioned. I'm aware that the OP requested zoom (which is featured therein), but thought it would be to repetitive and boring, so I added different effects as well as zooming.
SNIPPET
a {
text-decoration: none;
padding: 5px 10px;
border:1px solid red;
margin: 10px 0;
display: inline-block;
}
label {
cursor: pointer;
padding: 5px 10px;
border: 1px solid blue;
margin: 10px 0;
display:inline-block;
}
button {
cursor:pointer;
padding: 5px 10px;
border: grey;
font:inherit;
display:inline-block;
}
img#img {
width: 384px;
height: 384px;
display: block;
object-fit: contain;
margin: 10px auto;
transition: width 3s height 3s ease-in;
opacity: 1;
transition: opacity 1s 99999999s;
}
#zoomIn,
#zoomOut,
#spin {
display: none;
padding: 0 5px;
}
#zoomOut:checked + img#img {
width: 128px;
height: 128px;
transition: all 3s ease-out;
}
#zoomIn:checked + img#img {
width: 512px;
height: 512px;
transition: all 3s ease-in-out;
}
#spin:checked ~ img#img {
transform: rotate(1440deg);
}
img#img:target {
box-shadow: 0px 8px 6px 3px rgba(50, 50, 50, 0.75);
}
a.out:focus ~ img#img {
opacity: 0;
transition: opacity 1s;
}
a.in:active ~ img#img {
opacity: 1;
transition: opacity 1s;
}
.grey:focus ~ img#img {
filter: grayscale(100%);
}
<a href='#/' class='out'>FadeouT</a><a href='#/' class='in'>FadeiN</a>
<a href='#img'>ShadoW</a>
<br/><button class='grey' tabindex='0'>GreyscalE</button><br/>
<label for='spin'>SpiN</label>
<input type='checkbox' id='spin'>
<label for='zoomIn'>ZoomiN</label>
<input type='radio' id='zoomIn' name='zoom'>
<label for='zoomOut'>ZoomouT</label>
<input type='radio' id='zoomOut' name='zoom'>
<img id='img' src='https://i.ibb.co/5LPXSfn/Lenna-test-image.png'>
.container img {
margin: 100px;
transition: transform 0.25s ease;
cursor: zoom-in;
}
input[type=checkbox]:checked ~ label > img {
transform: scale(2);
cursor: zoom-out;
}
<div class="container">
<input type="checkbox" id="zoomCheck">
<label for="zoomCheck">
<img src="https://via.placeholder.com/200">
</label>
</div>
<html>
<head>
<title>Image Zoom</title>
<style type="text/css">
#imagediv {
margin:0 auto;
height:400px;
width:400px;
overflow:hidden;
}
img {
position: relative;
left: 50%;
top: 50%;
}
</style>
</head>
<body>
<input type="button" value ="-" onclick="zoom(0.9)"/>
<input type="button" value ="+" onclick="zoom(1.1)"/>
<div id="imagediv">
<img id="pic" src=""/>
</div>
<script type="text/javascript" language="javascript">
window.onload = function(){zoom(1)}
function zoom(zm) {
img=document.getElementById("pic")
wid=img.width
ht=img.height
img.style.width=(wid*zm)+"px"
img.style.height=(ht*zm)+"px"
img.style.marginLeft = -(img.width/2) + "px";
img.style.marginTop = -(img.height/2) + "px";
}
</script>
</body>
</html>

Enlarge image when hovering over parent element

Like many others I wanted to show an enlarged image when hovering over a thumbnail. I used a hover selector to enlarge the image which worked fine.
Instead of having the image shrink when I moved off the image, I wanted the image to shrink when I moved off area that was occupied by the original thumbnail which was 100px X 100px.
I put a div around it, sized it and put the :hover on it rather then the image. I thought because the enlarged image was positioned absolute it wouldn't enlarge the div.
The image still enlarges but it does not shrink unless the cursor moves off the enlarged image.
div.hov:hover >.thumbnail {
position:fixed;
top:100px;
left:50px;
width:800px;
height:auto;
display:block;
z-index:999;
}
div.hov{
width:101px;
height:101px;
float:left;
overflow:visible;
margin: 10px;
}
<p>
<div class="hov"><img src="./gm1.png" class="thumbnail" height="100" width="100" /></div>
<div class="hov"><img src="./gm2.png" class="thumbnail" height="100" width="100" /></div>
</p>
Is there any way to achieve this? The hosted version is here.
one way to do this is to show a new modal div on top of the original image. that way your original div doesn't enlarge. however, you'll need to use some javascript or jQuery
heres a fiddle to demonstrate: http://jsfiddle.net/k3oq1899/1/
don't mind the code, I put it together very quickly for you, but you can clean it up a bit.
html
<div class='image'>
<img src='http://www.online-image-editor.com//styles/2014/images/example_image.png'/>
</div>
<div id='modal'></div>
css
.image {
display: inline-block;
width: 100px;
height: auto;
}
img {
width: 100%;
height: 100%;
display: inline-block;
}
#modal {
display: none;
position: absolute;
top: 0;
left: 0;
}
jquery
$(function() {
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function (event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
if($('#modal').css('display') != 'none') {
$('#modal').css({
top: currentMousePos.y,
left: currentMousePos.x + 12
});
}
});
$('.image').on('mouseover', function() {
var image = $(this).find('img');
var modal = $('#modal');
$(modal).html(image.clone());
$(modal).css({
top: currentMousePos.y,
left: currentMousePos.x + 12
});
$(modal).show();
});
$('.image').on('mouseleave', function() {
$(modal).hide();
});
});
Instead of enlarging the image, think of actually creating two images, one big and one small one. Once you hover over the small one, you can make the big image visible or invisible when moving out of it.
use absolute positions, display:block and display:none and check if the z-index is right.
But is this really necessary?
The hovering does not seem convenient to me....
You can put an invisible DIV with same dimensions over the thumbnail, put it on top with z-index and use it for the hover-event. But you need a few lines of javascript (with jQuery in my example).
HTML
<div class="box">
<div class="thumbnail">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437" alt="">
<div class="overlay"></div>
</div>
<div class="large-image">
<img src="http://vignette4.wikia.nocookie.net/mrmen/images/5/52/Small.gif/revision/latest?cb=20100731114437" alt="">
</div>
</div>
Javascript (jQuery)
$('.overlay').hover(
function () {
$(this).closest('.box').addClass('show-large-image');
},
function () {
$(this).closest('.box').removeClass('show-large-image');
});
CSS
.box {
padding: 200px;
}
.thumbnail {
position: relative;
display: inline-block;
border: 1px solid #888;
}
.overlay {
z-index: 1;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.large-image {
display: none;
position: absolute;
top: 0;
left: 0;
width: 500px;
}
.large-image img {
width: 100%;
}
.box.show-large-image .large-image {
display: block;
}
Example: http://jsfiddle.net/dx0d1ceh/

How to position 3 images on top of one another and retain responsiveness using just CSS?

I have 3 images I'd like positioned on top of one another "centered" and would like to retain a responsive design.
Currently, I have to employ js during the resize of the window to position the images correctly. Is there a pure CSS way of doing this?
Here is the jsfiddle of what I have working.
https://jsfiddle.net/zt2Lca7v/
<div id="box">
<img id="back" src="http://esurf.us/x/csstry001/back.png" class="img-responsive" />
<img id="front" src="http://esurf.us/x/csstry001/front.png" class="img-responsive" />
<img id="vline" src="http://esurf.us/x/csstry001/vline.png" class="img-responsive" />
</div>
body {background-color:black;margin:0;padding:0;}
#box{position:relative;display:block;width:100%;margin:0 auto;}
#back
{
width:100%;
display:block;
margin: 0 auto;
position:absolute;
}
#front
{
display:block;
position:absolute;
width:34.0037%
}
#vline
{
display:block;
position:absolute;
width:2.7422%
}
#media only screen and (min-width: 769px) {
#box{width:90%;}
}
function resetimgpos()
{
var imgb = document.getElementById("back");
var wb = imgb.clientWidth;
var hb = imgb.clientHeight;
var imgf = document.getElementById("front");
var wf = imgf.clientWidth;
var hf = imgf.clientWidth;
var tf = ((hb - hf)/2) + 'px';
var lf = ((wb - wf)/2) + 'px';
$("#front").css({top: tf});
$("#front").css({left: lf});
var imgl = document.getElementById("vline");
var wl = imgl.clientWidth;
var hl = imgl.clientWidth;
var ll = ((wb - wl) / 2) + 'px';
$("#vline").css({left: ll});
}
$(function() {
$(window).resize(function(){
resetimgpos();
});
resetimgpos();
});
Thanks in advance.
Your problem is to center image in div which size you don't know.
Change #back image position to relative thus it will stretch parent div.
Set position of two other images to absolute and set top: 50% and left:
50% to position their left top corner in center of parent div.
Use transform: translate(-50%, -50%) on circle image.
Use transform: translateX(-50%) on line image.
Translate set to -50% moves div 50% of its own width/height to left/top.
See Fiddle.
I know my English is not very good but I hope you will understand it.
EDIT:
Of course for line image you don't need top: 50%, sorry for my mistake.
You could use %, margin and absolute:
http://codepen.io/anon/pen/zGgmyQ
#box {
position: relative;/* you need this ! */
/*demo purpose START */
background: linear-gradient(to left, transparent 50%, rgba(0, 0, 0, 0.2) 50%), linear-gradient(to top, transparent 50%, rgba(0, 0, 0, 0.2) 50%);
}
#box:hover img {
opacity: 0.35;
/*demo purpose END */
}
#back {
display: block;
width: 100%;
}
#front {
position: absolute;
top: 50%;
left: 50%;
width: 10%;
margin: -5% 0 0 -5.2%;/* tune this if new image or different shape */
z-index: 1;
}
#vline {
position: absolute;
top: 0;
left: 50%;
height: 100%;
margin-left: -1.5%/*tune this if new image or different shape*/
}
<div id="box">
<img id="back" src="http://esurf.us/x/csstry001/back.png" class="img-responsive" />
<img id="front" src="http://esurf.us/x/csstry001/front.png" class="img-responsive" />
<img id="vline" src="http://esurf.us/x/csstry001/vline.png" class="img-responsive" />
</div>
When you set a width or a height to an image, it keeps it's ratio. (the line is here 100% tall and the dialer is 10% width)
You may adjust size and margins to your real needs.
As mentioned by #sajran. You can use the translate to align the image vertically center.
Here is the working fiddle link:
http://jsfiddle.net/aL72r8qf

How to transition 2 divs at the same time?

I'm trying to make an animated menu that when I hover over it , the background (or image) reduces and at the same time the text expands.
Thats my style sheet :
.menus {
float: left;
background-image: url(images/menus_bg.png);
width: 208px;
height: 283px;
}
.menusimg {
width: 208px;
height: 283px;
position: absolute;
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center center;
background-image: url(images/menu1.png);
}
.menusimg:hover {
background-size: 80% 80%;
}
.menusimg, .menusimg:hover {
-webkit-transition: background-size 0.2s ease-in ;
}
.menustxtbox {
font-family: MP;
padding-top: 240px;
width: 208px;
height: 283px;
color: #4c4c4c;
font-size: large;
text-shadow: gray 0.1em 0.1em 0.2em;
}
.menustxtbox:hover {
padding-top: 235px;
font-size: x-large;
color: #4fa3f9;
}
.menustxtbox, .menutxtbox:hover {
-webkit-transition:font-size 0.1s linear;
-moz-transition:font-size 0.1s linear;
}
and the html :
<div class="menus">
<div class="menusimg">
</div>
<div class="menustxtbox">
Text
</div>
</div>
Any ideas? A simple Java script or anything that will solve this problem? :)
Thank you in advance ^^
I second what ntgCleaner said.
In addition you can use:
$('.menus').hover(function(){
$('.menusimg').addClass('active');
$('.menustxtbox').addClass('active');
}, function(){
$('.menusimg').removeClass('active');
$('.menustxtbox').removeClass('active');
});
And your css would have:
.menusimg.active, .menusimg.active{
-webkit-transition: background-size 0.2s ease-in ;
}
etc.
Well, without any code to see that you've done anything or tried anything with javascript, I would suggest this:
Change your CSS to make real sizes of font size first:
.menustxtbox {
font-size:40px;
}
then make some jquery
$('.menus').hover(function(){
$('.menusimg').animate({width: "100px"});
$('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$('.menusimg').animate({width: "208px"});
$('.menustxtbox').animate({fontSize: "40px"});
});
Then delete your :hover css styles
And if you want to use hover, I would suggest looking into hoverintent
UPDATE for a comment below
To do this for each separate menu item, you will have to name things a certain way. Here's an example.
HTML
<div class="menu">
<div class="menuItem" id="menu1">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu2">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu3">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
</div>
Then with jQuery, you will have to use $(this) and .children()
$('.menuItem').hover(function(){
$(this).children('.menusimg').animate({width: "100px"});
$(this).children('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$(this).children('.menusimg').animate({width: "208px"});
$(this).children('.menustxtbox').animate({fontSize: "40px"});
});
When you use $(this), you will do whatever you want to the specific thing you are trying to use. Then you just go up or down from there using parent or children to do something to either of those.

Resources