Hi I am trying to rotate an image when i hover over a div using Rotate and Transform-Origin. It was works when the image is centered in the div but when i change the vertical position of the image and make the relevant changes to the Transform-origin values the image still rotates but is slightly off center. Any ideas would be appreciated.
jsfiddle here (only seems to work in firefox)
http://jsfiddle.net/boyle/U3yLk/
html
<div class="box">
<div class="c">
<img class="pic" src="p.png"/>
</div>
css
.box{
width: 200px;
height: 300px;
background-color: #4781AA;
display:block;
}
.c{
width:200px;
height:300px;
display:block;
transition: all 1s ease;
}
.c:hover{
transform: rotate(180deg);
transform-origin: 100px 150px;
}
.pic {
position: relative;
left:50px;
top: 100px;
}
This also only seems to work in Firefox!
Cheers
try this
.transform{
transform:rotate(60deg);
-ms-transform:rotate(60deg);
-moz-transform:rotate(60deg);
-webkit-transform:rotate(60deg);
-o-transform:rotate(60deg);
}
Related
I have a div and im trying to scale it(just the Y) on hover.The problem is that it works well without transition.When i use transition,the div scales at top a bit and then goes down,check the fiddle.The question is how to prevent div from scalling like that?I want it to scale straight down,without this bouncing to top.
http://jsfiddle.net/q9akawr6/21/
HTML
<div></div>
CSS
div{
width:100px;
height:100px;
margin:100px;
background-color:red;
transition:.2s;
}
div:hover
{
transition:.2s;
transform-origin:top;
transform:scaleY(2.0);
}
As Niet says, or just put this in the div{} rule, rather than div:hover{}:
transition:.2s;
transform-origin:top;
for the same reason (to avoid a transition on transform-origin at the wrong time).
the div bouncing due to you margin area. I try to change your code. check the following
HTML:
<div class="container">
<div class="demo"></div>
</div>
CSS:
div.container
{
width:300px;
height:300px;
border:1px solid gray;
}
div.demo{
width:100px;
height:50px;
margin: 100px auto;
background-color:red;
transition:.2s;
transform-origin: left top;
}
div.demo:hover
{
transition:all .2s linear;
transform-origin: top;
transform:scaleY(2.0);
}
How can I make a div that has vertical align:top, change it's position to vertical-align: middle, but have a smooth animated transition through those states?
I can't get it to work, is vertical-align non transitionable?
Code:
.outer{
width:200px;
height:200px;
background:red;
display:table;
text-align:center;
}
.inner{
width:100px;
height:100px;
vertical-align:bottom;
display:table-cell;
transition:all 2s;
}
.inner:hover{
vertical-align:middle;
}
Here's the fiddle: https://jsfiddle.net/7amp783t/
Instead of changing the vertical-align property, use transform: translateY() to move up and down.
I've had a fiddle and got this code to work:
.outer{
width:200px;
height:200px;
background:red;
display:table;
text-align:center;
}
.inner{
width:100px;
height:100px;
display:table-cell;
vertical-align: bottom;
transition: all 2s ease-in-out;
}
.inner:hover{
transform: translateY(-50%);
}
The translateY(-50%) moves the text "up" (hence the -) by 50% of the height of its parent box.
EDIT You don't need to worry about setting the position: relative of the parent div. I've removed it for clarity.
I've updated your JSFiddle, also.
if you want to use vertical-align, you should not use inside a table-cell but with 2 elements side by side, where you can set values around the line-height they produce. In this case, vertical-align can take lots predefined values or numerics values.
https://www.w3.org/wiki/CSS/Properties/vertical-align#Values
Because your example gives an height of 200px, we may play around this : https://jsfiddle.net/7amp783t/5/
.outer{
font-size:18px;/* whatever */
width:200px;
height:200px;
background:red;
text-align:center;
}
.outer:before {
content:'';
display:inline-block;
height:100%;/* here the line is 100% height of container: set to 200px */
vertical-align:calc(-200px + 1em); /*chrome instead bottom */
}
.inner{
vertical-align:0;/* from bottom : calc(-200px + 2em) go all the way down minus room for text */;
display:inline-block;
transition:all 2s;
}
.outer:hover .inner{/* outer, else you need to follow inner */
vertical-align:calc(-100px + 1em);/* lets go half way */
}
<div class="outer">
<div class="inner">
Hover me box
</div>
</div>
CSS Transitions defines vertical-align as animatable, but only when interpolating between two length values.
┌────────────────┬───────────┐
│ Property Name │ Type │
├────────────────┼───────────┤
│ vertical-align │ as length │
└────────────────┴───────────┘
Therefore, transitions between bottom and middle won't be smooth.
If you were using vertical-align to align an inline-level element relatively to its line box, you could try using length values.
However, you are using it on a table cell, which has a different behavior, as defined in Table height algorithms. In particular, length values don't apply to table cells.
I think you have to use Jquery to create a sliding animation. You can use jQuery's toogle function to do so.
http://api.jquery.com/toggle/
http://api.jquery.com/slidetoggle/
Try transform instead of vertical aligning it to middle. This code will do same what you are trying to accomplish. Change your hover state to include translateY(-50%)
Working Demo
.outer{
width:200px;
height:200px;
background:red;
display:table;
text-align:center;
}
.inner{
width:100px;
height:100px;
vertical-align:bottom;
display:table-cell;
transition:all 2s;
}
.inner:hover{
transform: translateY(-50%);
}
u can try this sample:
using the transform: translateY(-50%); method
css vertical align animation
.block {
background: orange;
height: 500px;
}
.centered {
text-align: center;
background: pink;
position: relative;
top: 0;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
.block:hover .centered {
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
top: 50%;
}
let me know if u need further help
position:relative can be an easy way:
.outer {
width: 200px;
height: 200px;
background: red;
display: table;
text-align: center;
}
.inner {
position: relative;
top: 0;
display: table-cell;
transition: all 2s;
}
.inner:hover {
top: 50%;
}
<div class="outer">
<div class="inner">
Hover me
</div>
</div>
i have a div which is box and a 'p' element whose opacity is set to 0. when i hover over the div i want the 'p' elements opacity to change to 1. i have the following code . its looks proper to me but its not working. i could not figure out the problem with it. can some one help me. thanks in advance.
HTML:
<p class="se">Hover over the div element below</p>
<div class="box"></div>
css:
.se{
position: relative;
color:red;
opacity:0;
}
.se{
-webkit-transition: opacity 2s;
transition: opacity 2s;
}
.box{
position: relative;
left: 400px;
width: 100px;
height: 100px;
background: red;
}
box:hover + .se{
opacity:0;
}
jsFiddle http://jsfiddle.net/2f1k5yq4/
CSS selector +
Any element that is the next sibling of a previous element (that is: the
next child of the same parent)
.box {
position: relative;
left: 400px;
width: 100px;
height: 100px;
background: red;
}
.se {
color: red;
opacity: 0;
position: relative;
transition: 1s linear;
}
.box:hover + .se {
opacity: 1;
}
<div class="parent">
<div class="child">
<div class="box"></div>
<p class="se">Hover over the div element below</p>
</div>
</div>
This is actually a kind of annoying problem with just CSS. I'd prefer using Javascript, especially if you already have jQuery loaded into your site.
But, that said, this can sort of be done in CSS. I'm going to assume you just want to show/hide an element, so I'll use display for the example rather than opacity, so modify as needed to use a transition.
The first problem you have is that you box:hover rather than .box.hover. The second problem is a bit more annoying. Abhitalks is correct that +, the adjacent sibling selector, only selects the next sibling, so you can't have the text above the div that will show it. If, however, you switch the order, moving the div above the text, it works. You could use some clever positioning, floating, etc. in order to make the order of their appearance different than their order in the markup, if you wanted.
.se{
display: none
}
.box{
width: 100px;
height: 100px;
background: red;
}
.box:hover + .se{
display: block;
}
<div class="box"></div>
<p class="se">Hover over the div element below</p>
Our designer wants to do that:
But I can't figure out a good way to do this triangle crop:
With an :after that takes all the width and uses some kind of borders trick to make a triangle
With a big :after element that is rotated and white, but it should not hide any other text
With some magic filter I don't know?
By using a canvas, cropping it in JS, then loading the image as a base64 url? (Maybe overkill :D)
What do you think?
Edit: version 2: http://jsfiddle.net/mtaU8/4/ works with changing bg.
Here ya go: http://jsfiddle.net/mtaU8/
HTML: (I used a div with a background, but you could easily use an img element.)
<div class="container">
<div class="img"></div>
</div>
CSS: (mostly fluff for setup, but basically use transform:rotate() on an :after content, then position it so it slices your picture nicely. Contain all that in your container and you're good to go.)
.container {
width: 250px;
height: 100px;
position: relative;
overflow:hidden;
}
.img {
width: 250px;
height: 100px;
background-color: blue;
position: relative;
}
.img:after{
content:"";
position: absolute;
width: 400px;
height:125px;
background-color: white;
top:90px;
left:-20px;
transform: rotate(5deg);
-moz-transform: rotate(5deg);
-webkit-transform: rotate(5deg);
}
I'd suggest using the CSS clip property:
.crop {
position: absolute;
clip: rect(110px, 160px, 170px, 60px);
}
The clip property's rect value represents the section of the image that will be cropped. Here's a demo.
What's the best way (if any) to make the inside box transparent so the image can be seen with no opacity (clear image) and the rest of the outer box opaque. So far this is what I'm doing:
<style>
#a {
background-color: black;
float: left;
} #b {
opacity : 0.4;
filter: alpha(opacity=40);
} #div {
position: absolute;
height: 30px;
width: 30px;
top: 90px;
left: 90px;
border: 1px solid #FFF;
background: transparent;
}
</style>
<div id="a">
<div id="b">
<img src="http://clagnut.com/images/ithaka.jpg" />
</div>
</div>
<div id="div"></div>
Any ideas? thx
The maximum opacity of an element is the opacity of its parent element. So if div#b has an opacity of 40%, if his children have 100% opacity in style they will also be 40% absolute opacity.
To accomplish what you're describing (at least what I think you're describing), one way could be to have both the transparent wrapper and the image children of a parent div with relative positioning. You can absolutely position both of the children inside of that wrapper so that the image shows up on top of the transparent box.
Edit: Here is the code for the effect you are describing. My example has a 480 x 320 image, and a 30-pixel border:
<style>
#back {background-image:url(mypicture.jpg);
width:480px;
height:320px;
position:relative;}
#middle {position:absolute;
width:480px;
height:320px;
background-color:#000;
opacity:0.4;
filter:alpha(opacity=40);
top:0;
left:0;}
#front {position:absolute;
width:420px; /* 30px border on left & right */
height:260px; /* 30px border on top & bottom */
background-image:url(mypicture.jpg);
background-position:-30px -30px; /* compensate for the border */
top:30px;
left:30px;}
</style>
<div id="back">
<div id="middle">
</div>
<div id="front">
</div>
</div>
If I understand you correctly, try using just one div (i.e. get rid of the outer one with ID "a") and setting a colored border around it. Or you could get more flexibility by "faking" a border using 4 divs for the left, right, top, and bottom edges and 4 more for the corners.
It's kind of hard to know what you mean without an example page, or screenshots of what you expect and what you're actually getting.
EDIT: I was about to edit in basically the same thing Rex M wrote. Here's another (although idealistically inferior) way to do it:
<style>
#a {
float: left;
position: relative;
}
div.overlay {
opacity: 0.4;
background-color: black;
position: absolute;
}
#t {
left: 0; top: 0; height: 90px; width: 450px;
}
#b {
left: 0; top: 120px; height: 218px; width: 450px;
}
#l {
left: 0; top: 90px; height: 30px; width: 90px;
}
#r {
left: 120px; top: 90px; height: 30px; width: 330px;
}
</style>
<div id="a">
<div id="t" class="overlay"></div>
<div id="b" class="overlay"></div>
<div id="l" class="overlay"></div>
<div id="r" class="overlay"></div>
<img src="http://clagnut.com/images/ithaka.jpg">
</div>
If you want to be sure that the images have a certain color for a background, you could just as well stick a background to all IMG-elements in your stylesheet:
div#a img { background: #FFF; }
Anyhow, the filter-property in CSS should not be relied upon, as it is not part of the official specifications for CSS 2.1.
I might have misunderstood the question, though. Could you rephrase it or provide pictures of expected results?
To follow on what Rex M said, you'll need to change things so that the non-transparent elements aren't children of the transparent elements.
You can use absolute or relative positioning to line up your "border" with the picture, although this can often have inconsistencies between browsers.
The most painless way off the top of my head is to use javascript to get the top and left pixel locations of the image and set the top/left css properties of the border to match (and set the size of the border to that of the image).
UPDATE:
The asker showed an example of what he is trying to recreate. In the example linked, the shaded areas (the "not selected" area) of the picture is created by 4 divs.
The top and bottom divs are the full width of the image, and are set to have a height that is the difference between the top/bottom of the selection box and the top/bottom of the image respectively.
The side divs have height and width modified so that they fill in the "side areas" of the image.
The sizes are updated via a mousemove event.