This question already has answers here:
How to align a <div> to the middle (horizontally/width) of the page [duplicate]
(27 answers)
Closed 9 years ago.
I'm trying to achieve centered vertical and horizontal alignment of a div.
This is the styling I'm using:
.box{
position:fixed;
display:block;
width:200px;
height:400px;
top:50%;
left: 50%;
width: 50%;
transform: translateX(-50%) translateY(-50%);
background:#ccc;
}
This style works perfectly in Firefox but not in Chrome. Here's the example: http://codepen.io/0leg/full/HJjrK
The interesting thing is that I lifted this styling from a modal window on this tutorial http://tympanus.net/Development/ModalWindowEffects/, and for some reason this works perfectly in webkit browsers...
That is simply because in even the latest version of Chrome, you will need to use the vendor prefix -webkit- for CSS3 transforms. Mozilla Firefox has been supporting unprefixed transform since v16 (current v25), and ironically so is the current version of IE. More information on browser support is available here: http://caniuse.com/transforms2d
Therefore, use the vendor prefix (just -webkit- is sufficient, unless you want to support older versions of IE and Firefox, then use their respective vendor prefixes, too):
.test {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background: red;
width: 200px;
height: 200px;
}
http://codepen.io/terrymun/pen/zCgkI
As you know the height and width of the div, I would change your CSS to this:
.box{
position:absolute;
width:50%;
height:400px;
top:50%;
left: 50%;
margin-top: -200px; /* Half the height of the div */
margin-left: -25%; /* Half the width of the div */
background:#ccc;
}
You're moving the div half way down and across the page, and then negatively margining it back by half of it's width.
http://jsfiddle.net/davidpauljunior/utPhs/2/
Note: You had two width declarations, I presumed you wanted the second one (50%), so removed the first one. I changed position fixed to absolute but it works with both, and I removed the display:block as <div> is already a block level element.
Related
In the following code why do we use the webkit and ms keywords?
#svgelem {
position: relative;
left: 50%;
-webkit-transform: translateX(-20%);
-ms-transform: translateX(-20%);
transform: translateX(-20%);
}
EDIT: The ms- and webkit- keywords are used so each of the different CSS processors versions (microsoft (ms) and webkit) know how to handle that line. This is because of experimental features, like transform, being added by each of the CSS processors at different times.
The typical use of a block of CSS like this is used to move an element to the centre of it's parent object on the horizontal axis.
The idea is to move the element to so the left edge is in the middle of the parent:
#svgelemn {
position: relative;
left: 50%;
}
Now that the element is just to the right of the middle (remember that it's the left edge that is in the middle), you need to move the element to the left by 50% of it's own width (not it's parents width). Because we're moving the element to the left, we also need to invert the percentage so it's negative (-50%). So now you add the transform section:
#svgelemn {
position: relative;
left: 50%;
-webkit-transform: translateX(-50%); /* Webkit specific transform */
-ms-transform: translateX(-50%); /* Microsoft specific transform */
transform: translateX(-50%); /* Generic transform (all evergreen browsers) */
}
The code that you have only makes a final adjustment of only 20%, so that's not quite the middle.
You can see an example here. You can see how the top element is in the middle, while the original code makes it slightly off centre.
I have jquery adding a class to scale a div in certain circumstances:
$("#wrapper").addClass("doubleDiv");
The css:
.doubleDiv{ transform: scale(2); }
#wrapper { height:100%; position:relative; z-index:2; background-color:#111; max-width:320px; min-height:480px; margin:0px auto; }
It doubles the size fine, but the div's content gets shifted up past the top of the browser, so that roughly the top third is hidden, and you cannot scroll further up.
I removed each of the styles in #wrapper one by one, until none were left. Apart from screwing up the layout, the same thing happens when the scale is carried out.
To eliminate the chance of any of my jquery causing it, I coded
alert('stop1');
$("#wrapper").addClass("doubleDiv");
alert('stop2');
The display problem occurs before 'stop2' is displayed.
What else could cause this?
Cheers
Demo
you need to add transform-origin
css
.doubleDiv {
transform: scale(2);
transform-origin:50% 0%;
-ms-transform-origin:50% 0%;/* IE 9 */
-webkit-transform-origin:50% 0%; /* Chrome, Safari, Opera */
}
Transform scale scales the object in place. Use transform-origin to define from where you want to scale. Because scaling does not affect positioning at all and the default scaling point is center centre, it moves off screen. Check the follow code to see how it solves this problem:
<html>
<head>
<style type="text/css">
#div {
-webkit-transform: scale(2,2);
-webkit-transform-origin: top left;
background: red;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="div"></div>
</body>
</html>
I am trying to create a box with a jagged edge, that can actually be used as a HTML element should be, and can resize etc.
Finally got my head around border-image, got it looking nice, and then when I rotate it, it gets a gap between the border-image and the main fill:
I googled it, and found an answer on SO telling someone to set
-webkit-backface-visibility: hidden;
This cleared it up, but obviously only in webkit browsers.
I tried using -moz-backface-visibility as well, but it didn't clear the issue up in Firefox.
Any suggestions?
jsFiddle
e: I actually thought I may be able to fix it by setting a background color, and then setting the background-clip to padding-box, but honestly it just left me in the same position.
One trick that fixes the problem both in Webkit and FF is setting perspective (instead of backface visibility)
.box.one {
-webkit-transform: perspective(999px) rotate(1deg);
-moz-transform: rotate(1deg);
-ms-transform: rotate(1deg);
-o-transform: rotate(1deg);
transform: perspective(999px) rotate(1deg);
}
fiddle
Adding an after pseudo class with negative margin seems to fix the Firefox issue.
.rough:after {
content: "";
display: block;
margin: -1px;
height: 302px;
background: black;
}
Fiddle demo: http://jsfiddle.net/Wkk7W/3/
Note that the display:block seems to be an essential part of my hack/fix.
Update: Depending on your plans for content inside the div, that exact example might not suit. However, I think the concept could be tweaked depending on your requirements - e.g. using a 3px wide black border instead of a background fill, and using position:absolute to allow other text to be layered on top of the box.
Gonna answer myself, because this solution actually covers my needs of it being "as a html element should be, and can resize etc", even though I developed this solution from Grants answer.
http://jsfiddle.net/Wkk7W/6/
Set the element to position:absolute, then give it a pseudo element with:
content: "";
display: block;
position: absolute;
top: 0;
width: 102%;
margin: -1px 0 0 -1%;
height: 102%;
background: black;
z-index: -1;
This way it keeps the elements width and height, z-index: -1 to put it behind the text. It might not require the display:block, i didn't check.
There are still a few tiny gaps but they are basically impossible to cover and I am happy with it the way it is.
First of all, an image of what I am trying to acheive:
Sample here:
http://i.imgur.com/3BpFF.png
The white box with the word 'div' in it is obviously the div I have. For my purposes, it's a div centered in a page using width:500px; margin: 0 auto;. What I want is to be able to align some rotated text (using -moz-transform: rotate(90deg) or alternatively prefixed rotates) along the top of the div, like the word 'Holy' above (sample text). I would also like to set the baseline on that div, though it isn't that important.
By the way, I used some absolute positioning in Firebug to get the text aligned there - it was hacked there using per pixel positioning. It's not very flexible (if at all) because once I increase the font size or change the position of the div, it's broken.
Also: I am open to using SASS and other such things (I don't have any experience with it yet, but I do I think it allows use of variables which may help).
When you can use CSS transform it means you can use pseudo elements in your CSS code. Then I will add that "Holly" part via :after pseudo element.
div:after{
content:"Holy";
line-height:20px;
position:absolute;
background:yellow;
padding:0 10px;
left:100%; top:0;
-webkit-transform:rotate(90deg) translateY(-100%);
-webkit-transform-origin:0 0;
}
As you can see I've use translateY to move this part out of the div, because we rotated the thing before then translateY will work as translateX.
transform-origin is set to 0 0.
This code is independent from you div size.
Look at it live here:
http://jsbin.com/akaziy/2/
You can place something like this in your .css file (the margin-top & margin-bottom are just examples)
div {
width:500px;
margin: 0px auto;
}
.holly {
margin-top:20px;
margin-left:520px
/* Safari */
-webkit-transform: rotate(90deg);
/* Firefox */
-moz-transform: rotate(90deg);
/* IE */
-ms-transform: rotate(90deg);
/* Opera */
-o-transform: rotate(90deg);
/* Internet Explorer 9*/
-ms-transform: rotate(90deg);
/*undefined prefix*/
transform: rotate(90deg);
}
This question already has answers here:
How to center an element horizontally and vertically
(27 answers)
How can I horizontally center an element?
(133 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Closed 3 years ago.
when i use top:50% and left:50%
the box is not directly in center. of course when the box is very small, it appears to be centered. but when box is a bit big, it looks as if it's not centered.
how can i resolve this ?
top and left correspond to the top-left corner of your box. What you're trying to do is have them correspond to the center. So if you set margin-top and margin-left to negative of one-half the height and width respectively, you'll get a centered box.
Example for a 300x200 box:
width: 300px;
height: 200px;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -100px;
using translate will perfectly achieve that. simply apply this
div.centered {
position: fixed; /* or absolute */
top: 50%;
left: 50%;
/* bring your own prefixes */
transform: translate(-50%, -50%);
}
source
Horizontal: Use a fixed width and
margin-left: auto;
margin-right: auto;
vertical: That's not that easy. You could use
display: table-cell
for the surrounding DIV and then give it a
vertical-align: middle
You can assign the box a fixed width and heigth, and then give it's margin-top and margin-left properties the negative half of the height and width.
EDIT: Example
div.centered {
width: 500px;
height: 400px;
top: 50%;
left: 50%;
position: absolute;
margin-top: -200px;
margin-left: -250px;
}
One way is to assign a specific width to the box, then halve the remaining distance on each (left and right) side. This may be easier if you use percentages instead of pixel widths, e.g.,
<div style="margin-left:25%; margin-right:25%">...</div>
This leaves 50% width for the div box.
The very bizarre CSS "language" does not provide a simple way to center a element in the screen. Kludges must be made! This is the only solution I came to elements that are AUTO in both height and width. Tryed in FF19 (Win+Mac), CH25 (Win+Mac) and IE9.
.overlay {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:#eee; /* aesthetics as you wish */
}
.overlay .vref { /* it is a vertical reference to make vertical-align works */
display:inline-block;
vertical-align:middle; /* this makes the magic */
width:1px;
height:100%;
overflow:hidden;
}
.overlay .message {
display:inline-block;
padding:10px;
border:2px solid #f00; /* aesthetics as you wish */
background-color:#ddd; /* aesthetics as you wish */
vertical-align:middle; /* this makes the magic */
max-width:100%; /* prevent long phrases break the v-alignment */
}
<div class="overlay">
<div class="vref"> </div>
<div class="message">whatever you want goes here</div>
<div class="vref"> </div>
</div>
body { text-align: center; }
#box {
width: 500px; /* or whatever your width is */
margin: 10px auto;
text-align: left;
}
The above would centre your box centrally horizontally on the page with a 10px margin at the top and bottom (obviously that top/bottom margin can be altered to whatever you want). The 'text-align' on the body is required for IE, which as usual doesn't quite get the hang of it otherwise. You then need the left text-align on your box (unless you want text it in centred too) to counteract the text-align center on the body.
Trying to centre vertically is just about impossible using pure CSS though. Though there's a vertical-align in CSS, it doesn't work like the HTML vertical align in tables, so in CSS 2 there's no in-built vertical align like the HTML one. The problem is that you're dealing with an unknown height - even if you know the height of your box, the height of the page is unknown, or rather what are you trying to fix the box in the centre of? The page? The viewport? The visible screen area's going to be different for everyone, depending on their screen resolution, browser, and all of the browsers interpret the height differently.
There are various methods that claim to have solved the problem, but usually they don't reliably work in all browsers. I found this one the other day, which doesn't seem bad, but it doesn't work in Google Chrome (works in Firefox and Opera, but I didn't get chance to check out IE). There's an interesting discussion on the problem though on this thread on Webmaster World that summarises the various methods and pros and cons of them and is well worth a look.
Edit:
Dav's solution in the first response works okay as long as you (or the visitor to the site) don't increase the font size or line height. The container will be centred, but as soon as the font size is increased or more content added, it'll overflow the container.