CSS: rotate image and align top left

2020-02-26 06:10发布

问题:

I am trying to rotate an image using a CSS transform such that it stays correctly aligned within the surrounding div, i.e. the top left corner of the image should be aligned with the top left corner of the div.

As you can see here (-> click on [rotate]) this does not work. Is there a way to fix this?

(Note that I'd be using this in an online image viewer so I cannot hardcode an offset for the rotated image. There's a lot of similar questions but I haven't found this exact question.)

回答1:

If you want it to be done in CSS, this is the way:

.rot90 {
    -webkit-transform: translateY(-100%) rotate(90deg); /* Safari */
    -moz-transform: translateY(-100%) rotate(90deg); /* Firefox 3.6 Firefox 4 */
    /*-moz-transform-origin: right top; */
    -ms-transform: translateY(-100%) rotate(90deg); /* IE9 */
    -o-transform: translateY(-100%) rotate(90deg); /* Opera */
    transform: translateY(-100%) rotate(90deg); /* W3C */  
    -webkit-transform-origin: left bottom;
    -moz-transform-origin: left bottom;
    -ms-transform-origin: left bottom;
    -o-transform-origin: left bottom;
    transform-origin: left bottom;
}

updated demo

The trick is to rotate the image around the left bottom corner. Once done, it is down by 100% of the height; translate it and now it is ok.

To get the same effect for the inverse rotation: (hover to transform)

div:hover #myimage {
    -webkit-transform: translateX(-100%) rotate(-90deg); /* Safari */
    -moz-transform: translateX(-100%) rotate(-90deg); /* Firefox 3.6 Firefox 4 */
    -ms-transform: translateX(-100%) rotate(-90deg); /* IE9 */
    -o-transform: translateX(-100%) rotate(-90deg); /* Opera */
    transform: translateX(-100%) rotate(-90deg); /* W3C */  
    -webkit-transform-origin: top right;
    -moz-transform-origin: top right;
    -ms-transform-origin: top right;
    -o-transform-origin: top right;
    transform-origin: top right;
}
<div style="border: 1px solid red;">
  <img id="myimage" src="http://upload.wikimedia.org/wikipedia/mediawiki/a/a9/Example.jpg" style="border: 3px solid silver;" />
</div>



回答2:

Using some jQuery, you can get the offset of the parent, subtract that from the new rotated offset and use margin to put it back to the container. It works with all rotations. Here is the Fiddle.

JS:

function rotate(elm, deg) {
    var offsetContLeft, offsetContTop, offsetLeft, offsetTop, newLeft, newTop;
    $(elm).css('transform', 'rotate('+ deg +'deg)');
    // Get the container offset
    offsetContLeft = $(elm).parent().offset().left;
    offsetContTop= $(elm).parent().offset().top;
    // get the new rotated offset
    offsetLeft = $(elm).offset().left;
    offsetTop = $(elm).offset().top;
    // Subtract the two offsets.
    newLeft = offsetContLeft - offsetLeft;
    newTop = offsetContTop - offsetTop;
    // Apply the new offsets to the margin of the element.
    $(elm).css('margin-left', newLeft).css('margin-top', newTop);
}

$("#myrotate").click(function (e) { 
      // pass in the element to rotate and the desired rotation.
      rotate('#myimage', 90);
});


回答3:

From the answers given thus far I take it that there is no simpler approach than using JavaScript to "realign" the image. Let me therefore share the approach which I ended up using:

var step = 0;

$("#myrotate").click(
  function (e) { 
    step += 1;
    var img = $("#myimage");
    img.css('transform', 'rotate('+ step*90 +'deg)'); // could be extended to work also in older browsers
    var d = img.width() - img.height();
    img.css('margin-left', -d/2*(step%2));
    img.css('margin-top',   d/2*(step%2));
  }
);

myrotate is the id of the <a> which I abuse as switch, myimage is (guess) the id of the img to rotate.

Try it here.



回答4:

I don't know if there is a simplier way, but you can set margin of the image after rotation like this.

margin:68px -66px;

You can use js to get image width and height so it sets values accordingly to the size of image. I used manual way.

http://jsfiddle.net/YQktn/3/

EDIT:

You can always mess with

-webkit-transform-origin: 75px 75px;
-moz-transform-origin: 75px 75px;
-ms-transform-origin: 75px 75px;
-o-transform-origin: 75px 75px;
transform-origin: 75px 75px;

as found here: CSS "transform: rotate()" affecting overall design with "position: absolute" (not aligning properly)



回答5:

I take the @Lost Left Stack example and changed it to work with all rotations, and be repetitive. Resets margins for repetitive rotations. Also set right and bottom margins.

function rotateImage(elm, deg) {
    $(elm).css('margin-left', 0).css('margin-top', 0);
    $(elm).css('transform', 'rotate(' + deg + 'deg)');
    // Get the container offset
    var offsetContLeft = $(elm).parent().offset().left;
    var offsetContTop = $(elm).parent().offset().top;
    // get the new rotated offset
    var offsetLeft = $(elm).offset().left;
    var offsetTop = $(elm).offset().top;
    // Subtract the two offsets.
    var newOffsetX = Math.floor(offsetContLeft - offsetLeft) + 1;
    var newOffsetY = Math.floor(offsetContTop - offsetTop) + 1;
    $("#a").text(newOffsetX + "-" + newOffsetY)
    // Apply the new offsets to the margin of the element.
      $(elm).css('margin-left', newOffsetX).css('margin-top', newOffsetY)
          .css('margin-right', newOffsetX).css('margin-bottom', newOffsetY);
}
var rot = 0;
$("#myrotate").click(function (e) { 
rot += 15;
      rotateImage('#myimage', rot);
});

example: http://jsfiddle.net/v4qa0x5g/2/