Vertically center rotated text with CSS
Asked Answered
C

7

89

I have the following HTML:

<div class="outer">
    <div class="inner rotate">Centered?</div>
</div>

div.outer is a narrow vertical strip. div.inner is rotated 90 degrees. I would like the text "Centered?" to appear centered in its container div. I do not know the size of either div in advance.

This comes close: http://jsfiddle.net/CCMyf/2/. You can see from the jsfiddle that the text is vertically centered before the transform: rotate(-90deg) style is applied, but is somewhat offset after. This is particularly noticeable when div.outer is short.

Is it possible to center this text vertically without knowing any of the sizes in advance? I haven't found any values of transform-origin that solve this problem.

Costate answered 28/2, 2013 at 15:0 Comment(4)
Are you opposed to setting display: table on the elements? Because the 'standard' way to vertically align dynamic divs should work with the transform without issue: https://mcmap.net/q/45137/-how-can-i-vertically-center-a-div-element-for-all-browsers-using-cssWinged
I'm not opposed to display: table. This fiddle shows that the table solution has the same issues as the one above: jsfiddle.net/4d384Costate
Try putting the rotate class on the middle element. That should do it, but it looks like it messes up the width of the item. Might have to play around with the padding or width or height props, but it should be do-able: jsfiddle.net/digthedoug/jWYuqWinged
Fixing the width issue is significantly harder than you'd expect. Putting min-width: 16px; width: 16px on .outer results in the exact same non-centering as in the original question.Costate
A
179

The key is to set position top and left to 50% and then transformX and transformY to -50%.

.inner {
    position: absolute;
    top: 50%;
    left: 50%;
}

.rotate {  
    transform:  translateX(-50%) translateY(-50%) rotate(-90deg);
}

see: http://jsfiddle.net/CCMyf/79/

Adenitis answered 19/6, 2014 at 21:28 Comment(3)
Working with text elements instead of divs I had to add margin: 0 on the inner element to make the text center perfectly.Vang
Thank you so much. I was not so far. I don't know why but if I set the rotate rule first like this: transform: rotate(-90deg) translateX(-50%) translateY(-50%); it doesn't work, and if I put it last as your example shows, it works: translateX(-50%) translateY(-50%) rotate(-90deg);.Protozoology
@MaximeLafarie Damn me too! Just learned that transform have an execution orderFaizabad
F
6

It may be a bit late for answering that question, but I stumbled on the same issue and found some way of achieving it, by adding another div in the way.

<div class="outer">
    <div class='middle'><span class="inner rotate">Centered?</span></div>
</div>

and applying a text-align: center on that middle element, along with some positioning stuff:

.middle {
    margin-left: -200px;
    width: 400px;
    text-align: center;
    position: relative;
    left: 7px;
    top: 50%;
    line-height: 37px;
}

The .inner also gets a display: inline-block; to enable both rotate and text-align properties.

Here is the corresponding fiddle : http://jsfiddle.net/CCMyf/47/

Footrest answered 20/3, 2014 at 11:41 Comment(0)
P
5

The another option to rotate text 90 degree and center on axis Y is:

.rotate-centered {
    top: 50%;
    right: 50%;
    position: absolute;
    transform: scale(-1) translate(-50%, 50%);
    writing-mode: vertical-lr;
 }
<span class="rotate-centered">Text<span>

Example: https://codepen.io/wwwebman/pen/KKwqErL

But because of bad support in IE/EDGE writing-mode does NOT work there: https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode

Perhaps answered 26/12, 2019 at 19:17 Comment(0)
E
2

Can you add margin: 0 auto; to your "rotate" class to center the text.

.rotate {
  -webkit-transform: rotate(-90deg);
  -ff-transform: rotate(-90deg);
  transform: rotate(-90deg);
  width: 16px;  /* transform: rotate() does not rotate the bounding box. */
  margin: 0 auto;
}
Educt answered 28/2, 2013 at 15:4 Comment(1)
This does not work. Here's the fiddle updated with "margin: 0 auto": jsfiddle.net/CCMyf/3. You can see that the "?" in "Centering?" is much closer to the top than the "C" is to the bottom.Costate
P
2

The answer from 'bjnsn' is good but not perfect as it fails when the text contains space in it. For example he used 'Centered?' as text but if we changed the text to let suppose 'Centered? or not' then it will not work fine and will take the next line after space. Ther is not width or height defined for the inner div block.

.inner {
  font-size: 13px;
  font-color: #878787;
  position: absolute;
  top: 50%;
  left: 50%;
  background: #DDD;
}

https://jsfiddle.net/touqeer_shakeel/f1gfy1yy/ But we can make the whole text centered align properly, by setting the inner div width equal to height of the outer div, line-height of inner div equal to the width of the outer div and setting the display flex property for inner div with align-items:center and justify-content:center properties.

.inner {
  font-size: 13px;
  font-color: #878787;
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  justify-content:center;
  align-items:center;
  line-height:40px;
}
$('#height').on('change', function(e) {
  $('.outer').css('height', $('#height').val() + 'px');
  $('.inner').css('width', $('#height').val() + 'px');
});

updated fiddle https://jsfiddle.net/touqeer_shakeel/cjL21of5/

Phonsa answered 30/9, 2016 at 10:35 Comment(0)
S
0

Removing : margin-top: -7px; from .inner made the vertically rotated text centered for me. It also made the horizontal text not centered.

Just remove the above code?

Snapper answered 28/2, 2013 at 15:5 Comment(1)
This may make it closer to being centered, but it still isn't properly centered. You can see this clearly in this version of the fiddle: jsfiddle.net/CCMyf/4Costate
D
0

You could add this:

$('.inner').css('margin-top', $(this).parent().height() - 2*$(this).height());

To your .on('change') function, as you can see here: http://jsfiddle.net/darkajax/hVhbp/

Douglasdouglashome answered 28/2, 2013 at 15:8 Comment(2)
This works, though I would very much prefer a CSS solution if it's possible.Costate
did you find a CSS solution?Funiculus

© 2022 - 2024 — McMap. All rights reserved.