absolutely center CSS div with a caveat [duplicate] - html

I am trying to center an element vertically inside a parent element using css. The parent element has a dynamic height and I would like the parent box to scroll if the height of the parent is less than the height of the child. I tried using flex boxes and the transform: translate technique described here (https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/) to center the child. Both techniques worked, but resulted in strange scrolling behavior when the parent gets too small.
#wrapper {
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
position: absolute;
}
.center {
width: 200px;
height: 200px;
background-color: yellow;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
Here is a jsfiddle that shows what I mean: http://jsfiddle.net/snhpdL91/
Notice that if you scale the window down until the scroll bars appear the text "hello" at the top of the child is cut off, even when scrolled to the very top. How can I make it so that I can scroll across the full range of the child element?

You can use flexbox with auto margins:
Prior to alignment via justify-content and align-self,
any positive free space is distributed to auto margins in that
dimension.
It works because only positive free space is distributed.
#wrapper {
display: flex;
}
.center {
margin: auto;
}
#wrapper {
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
position: absolute;
display: flex;
}
.center {
width: 300px;
height: 300px;
background-color: yellow;
margin: auto;
}
<div id="wrapper">
<div class="center">Hello</div>
</div>

Related

Center div (vertically & horizontally) in a 100% height div (Bootstrap)

I'm trying to solve my problem since one week, and I really try everything !
I have a two column layout (left: content / right: description of the content).
I want this two columns full height page and the only way I found is :
body {
margin: 0;
height: 100%;
padding: 0;
}
#rightcol {
position: absolute;
top: 0;
bottom: 0;
right: 0;
overflow-y: scroll;
height: 100%;
text-align: right;
}
The closest way to center a div in my columns was to use (in CSS3) flexbox. But there is conflicts with the absolute position of my columns.
Here's the bootply I made to be more explicit :
http://www.bootply.com/1OovYNhx1E#
In this example, I'd like to center (horizontally and vertically) the <h1>TEXT</h1>
UPDATE
Bootply is a terrible tool. So I used Plunker to replicate your example. This includes Bootstrap and everything you had originally except:
.fluid-container and .row are combined.
#inner is now moved out of #leftcol
#inner has the rulesets previously mentioned.
Both columns changed height: 100vh
Added position: relative to body.
Added width:100% and height:100% to html and body elements.
#inner {
position: absolute;
left: 50%;
top: 50%;
bottom: -50%; /* This was added to offset the top: 50% which was keeping the #inner from scrolling any further to the top. */
transform: translate(-50%, -50%);
z-index: 9999;
}
PLUNKER
OLD
Use the following ruleset on your center element:
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
}
You weren't clear as to where this centered div should be center in relation to. If you want it to be centered in relation to viewport, (i.e. edge to edge of screen) then the center div shouldn't be inside any column. I f you want it centered within the left column, then it's in the correct place. Regardless, if you use this solution it will center itself perfectly inside of whatever you put it into.
SNIPPET
body {
position: relative;
margin: 0;
height: 100%;
padding: 0;
}
#leftcol {
position: absolute;
top: 0;
bottom: 0;
left: 0;
overflow-y: scroll;
height: 100%;
width: 50%;
text-align: left;
background: brown;
}
#rightcol {
position: absolute;
top: 0;
bottom: 0;
right: 0;
overflow-y: scroll;
height: 100%;
width: 50%;
text-align: right;
background: yellow;
}
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
outline: 3px solid red;
width: 25%;
height: 25%;
background: rgba(0,0,0,.4);
}
<div id='leftcol'></div>
<div class='center'></div>
<div id='rightcol'></div>
Finally find the answer HERE
With flexbox just add to your inner container :
margin: auto;
It will prevent the top scroll problem !

Translate(Y) vertical center method not working - slightly off center

I have this simple code to vertically and horizontally center a text element on a page:
body {
max-width: 1200px;
margin: 0 auto;
}
.container {
position: relative;
transform-style: preserve-3d;
height: 100vh;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%);
}
Doing this places the text in the in the vertical center of the container, but ever-so-slightly off-center to the right on the horizontal. I would think "left: 50%" would horizontally center it correctly, no?
Close, but you need to add translateX as well. Luckily, there's a nice shorthand for accomplishing both X and Y transform at the same time:
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
The reason it's slightly off-center is because left: 50% pushes the element so that it's left side is at 50% exactly. Adding the transformX(-50%) negates that extra space. See the snippet below:
.box-container {
position: relative;
height: 200px;
}
.center-box {
position: absolute;
background: black;
width: 50px;
height: 50px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="box-container">
<div class="center-box"></div>
</div>
If you can use flexbox then I would recommend using it. It makes this very simple:
body {
margin: 0;
}
.container {
height: 400px; /* Just for the snippet */
width: 400px; /* Just for the snippet */
background-color: #f4f4f4; /* Just for the snippet */
margin: 0 auto; /* Just for the snippet */
display: flex;
align-items: center;
justify-content: center;
}
<div class="container">
<div class="center">
This is centered
</div>
</div>
You can find about flexbox browser support from here: http://caniuse.com/#search=flex

Vertically align image in div that uses padding-bottom to lock ratio

I have a div that is using padding-bottom:100% to lock the aspect ratio of the div to 1:1 (for responsive purposes):
<div class="image-container">
</div>
css:
.image-container {
width: 100%;
height: 0;
padding-bottom: 100%;
background:yellow;
}
Now, I have an image inside of this container with width:100%. However, the image stays at the top and I can't use vertical-align:middle on the image.
Is there a way I can get this image centered vertically? JSFiddle: http://jsfiddle.net/g819gz2a/
Unfortunately I will need this to work for not only IE 9 but the deadly IE 8
You could do the following using absolute positioning:
JS Fiddle
(in example background of image made green to show its centered)
.container {
width:300px;
}
.image-container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
background:yellow;
}
img {
width:100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0px);
}
And for older browsers:
JS Fiddle
img {
background: green;
width:100%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
}

How to center an element vertically in css in a scrollable container

I am trying to center an element vertically inside a parent element using css. The parent element has a dynamic height and I would like the parent box to scroll if the height of the parent is less than the height of the child. I tried using flex boxes and the transform: translate technique described here (https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/) to center the child. Both techniques worked, but resulted in strange scrolling behavior when the parent gets too small.
#wrapper {
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
position: absolute;
}
.center {
width: 200px;
height: 200px;
background-color: yellow;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
Here is a jsfiddle that shows what I mean: http://jsfiddle.net/snhpdL91/
Notice that if you scale the window down until the scroll bars appear the text "hello" at the top of the child is cut off, even when scrolled to the very top. How can I make it so that I can scroll across the full range of the child element?
You can use flexbox with auto margins:
Prior to alignment via justify-content and align-self,
any positive free space is distributed to auto margins in that
dimension.
It works because only positive free space is distributed.
#wrapper {
display: flex;
}
.center {
margin: auto;
}
#wrapper {
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
position: absolute;
display: flex;
}
.center {
width: 300px;
height: 300px;
background-color: yellow;
margin: auto;
}
<div id="wrapper">
<div class="center">Hello</div>
</div>

Position absolute div in center of screen view

I want to place div that has absolute position in center of the screen view (scrolled or not scrolled).
I have this but its places div in mid od the document and not mid of current view.
#main {
width: 140px;
height:100px;
border: 1px solid Black;
text-align: left;
position: absolute;
top: 50%;
left: 50%;
margin-left:-70px;
margin-top:-50px;
}
Use the following CSS:
.centered {
position: fixed;
top: 50%;
left: 50%;
/* bring your own prefixes */
transform: translate(-50%, -50%);
}
Change position:absolute to position: fixed and you should be good to go!
When you say position - absolute, the reference div is the parent div that has a position - relative. However if you say position -fixed, the reference is the browser's window. which is wat you want in your case.
In the case of IE6 i guess you have to use CSS Expression
If you don't want to change your element's position to fixed, here is a solution with keeping your element absolut.
Since CSS's calc() is supported by all browsers now, here a solution using calc().
#main {
width: 140px;
height:100px;
border: 1px solid Black;
text-align: left;
position: absolute;
top: calc(50vh - (/* height */100px / 2));
left: calc(50vw - (/* width */140px / 2));
}
A bit more complex way is to use multiple outer boxes. This method works well with or without hard coded width/height of the middle box (background colors added just to show what each box does):
/* content of this box will be centered horizontally */
.boxH
{
background-color: rgba(0, 127, 255, 0.2);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
}
/* content of this box will be centered vertically */
.boxV
{
background-color: rgba(255, 0, 0, 0.2);
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
/* content of this box will be centered horizontally and vertically */
.boxM
{
background-color: lightblue;
padding: 3em;
}
<div>
some text in the background
</div>
<div class="boxH">
<div class="boxV">
<div class="boxM">
this div is in the middle
</div>
</div>
</div>
https://jsfiddle.net/vanowm/7cj1775e/
If you want display div in the middle regardless of the scroll position, then change position to fixed
Here is a solution using margin and position: fixed :
#main{
width: 140px;
height:100px;
border: 1px solid black;
/* Centering #main on the screen */
position: fixed;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
It centers the div by increasing the margin on all sides to fit the whole screen.
EDIT: I found out there is a shorthand for top,right,bottom,left that is inset. It has been implemented in major browsers and you can see the compatibility on other browsers here
So to absolutely center a div on a screen:
#main{
width: 140px;
height:100px;
border: 1px solid black;
/* Centering #main on the screen */
position: fixed;
margin: auto;
inset: 0;
}
I managed to place absolutely positioned text in the center with the following:
position: absolute;
text-align: center;
left: 1%;
right: 1%;
This is a variation of the answer from Kenneth Bregat. It maintains absolute positioning rather than fixed, plus it solves text wrapping issues mentioned in some answers. Don't forget that the parent will need relative positioning.
What about this trick:
position: absolute;
height:200px;
top: 0;
left: 1%;
right: 1%;
margin-left: -half_of_the_div;
left: 50%;
position: fixed;
example on codepen