Centre div inside div using display: table - html

I have the following:
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
display: inline-block;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>
I can't work out why the inner most div isn't being centred? I did look at some of the answers here regarding centring however I can't see what the problem is...
I want the hello to be centred vertically to the centre but not horizontally. All other divs are positioned how I want them. There is no error in the other divs they are positioned side by side for a reason. The only change I want is the hello div moved vertically to the centre

You are just overiding your inner div with
#outterFields div {
display: inline-block;
}
Just remove it or if you where intending a direct child do:
#outterFields > div {
display: inline-block;
}
#innerLabels,
#innerFields {
display: inline-block;
width: 200px;
height: 200px;
border-style: solid;
border-width: 1px;
vertical-align: top;
}
.innerLabel {
display: table;
border-style: solid;
border-width: 1px;
height: 100px;
width: 80%;
}
.innerLabel div {
display: table-cell;
vertical-align: middle;
border-style: solid;
border-width: 1px;
}
#outterFields {
background-color: red;
width: 60%;
min-width: 300px;
height: 300px;
}
#outterFields div {
/* display: inline-block; */
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel">
<div>hello</div>
</div>
</div>
</div>

Your outterfields display inline block is overwriting other display items. I came up with better solution for you. I haven't used table but used flex here learn about flex it's more worth.
#outterFields {
background-color:red;
width:60%;
min-width:300px;
height:300px;
}
#innerLabels, #innerFields {
display:flex;
align-items:center;
width:200px;
height:200px;
border: 1px solid #000;
}
.innerLabel {
display:flex;
align-items:center;
border: 1px solid #000;
height:100px;
width:80%;
}
.innerLabel div {
display:table-cell;
vertical-align: middle;
border: 1px solid #000;
}
<div id="outterFields">
<div id="innerLabels">
<div class="innerLabel"><div>hello</div></div>
</div>
</div>

The necessary and most often sufficient condition where you can center a div using a display: table-cell, is as follows:
<div id="a">
<div id="b">
<div id="c">Helo</div>
</div>
</div>
CSS as follows:
body, html {
height: 100%;
}
#a {
display: table;
width: 100%;
height: 100%;
}
#b {
display: table-cell;
vertical-align: middle;
}
#c {
margin: auto;
text-align: center;
}
You need html and body elements to actually span the entire height of the document area if you want your a div to be able to make use of its 100% height. If your use case demands height that does not depend on the height of the document body, you don't have to use the body, html selector.
When you use display: table the otherwise auto-expanding width for a div element (width: auto implicit rule) does not apply the same way anymore as elements with display: table use a conservative width calculation -- they only by default take as much space as the content requires. Since I am illustrating a "100% 100%" centering to you, I have width: 100% there to have the element expand to available parent width.
height: 100% is likewise needed to have the element expand to available parent height. It does not matter if its display: block as with regular div elements, or display: table -- you need to specify height if you want computed height that goes beyond content height.
The display: table-cell rule only works if there is an ancestor element with display: table, hence you need at least two elements inside one another to apply display: table-cell to the one that is contained in the other. You don't need to specify height because elements with display: table-cell occupy available parent height automatically.
vertical-align rule for the display: table-cell elements is the only case where the alignment applies to the content inside the element, as opposed to its usual behavior where it applies with regard to how the element is positioned within the parent. Meaning that in our case, the vertical-align tells the browser that everything contained in the element with display: table-cell is to be centered vertically within its computed height.
For the c element you would need margin: auto only if you had content that did not completely fill available parent width. Since div elements normally do, it is not necessary, but is forward thinking on my part -- in case you decide to use span or something else that computes its width conservatively. The text-align speaks for itself -- The anonymous textual content and text inside descendant elements, will be centered in the middle along horizontal axis.

Related

Centering a child in a parent narrower than itself

So I've come up with a way to center children in a parent that is smaller than itself. I'm not to keen on the extra markup it takes to accomplish, and I am wondering if there is a better way to accomplish this, with better meaning less extra markup/styling, or "cleaner" in general.
THE GOAL
Given a parent that is smaller (less wide), put the center of the child element in the center of the parent element dynamically without knowing the width of the child element or the parent element.
MY APPROACH
So my approach uses three nested spans (the element itself is of little consequence).
The first span has a width of 0px and is centered via margin: 0 auto. This gives us the center of the parent container.
The second span has a width of auto, a white-space of nowrap, and a display of inline-block. The display is the key here. This restores the natural width of the child element
the third span has a position of relative, and a left of -50%. This centers the span in relation to the parent by offsetting half of the width of the child in relation to the center of the parent.
THE QUESTION
Is there a cleaner/less "janky" way of doing this?
THE MARKUP
<div class="box">
<span class="first-wrap">
<span class="second-wrap">
<span class="third-wrap">
This should be centered in relation to the box;
</span>
</span>
</span>
</div>
THE STYLES
.box {
border: 1px solid red;
width: 20px;
height: 20px;
margin: 40px auto;
}
.box .first-wrap {
display: block;
width: 0px;
margin: 0 auto;
border: 1px solid blue;
}
.box .first-wrap .second-wrap {
display: inline-block;
white-space: nowrap;
width: auto;
border: 1px solid green;
}
.box .first-wrap .second-wrap .third-wrap {
position: relative;
left: -50%;
border: 1px solid black;
}
THE FIDDLE
https://jsfiddle.net/d3w1wom0/
Just delete your css and replace with the following:
.box {
display: flex;
justify-content: center;
border: 1px solid black;
}
If you want to change the width, and center things accordingly you can just add the following to the above .box class:
width: 60%;
margin: 0 auto;
.box {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
}
will center your text in the box

Positioning divs inside a container

I have a general, possibly beginner question about HTML.
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
max-width: 200px;
border: 1px solid red;
}
#item2 {
height: 100px;
max-width: 200px;
border: 1px solid blue;
}
<div id="container">
<div id="item1"></div>
<div id="item2"></div>
</div>
My question is, why do #item1 and #item2 divs go underneath each other as opposed to next to each other? Isn't it true that they are no longer block-level elements because I have specified a set width for them? Why are they not lined up next to each other inside of #container? The #container has more than enough width to accommodate both items.
Note: This is strictly for learning/curiosity. I know that I can use margins and positioning to place them where I want to. However, I'm just curious as to why it behaves this way.
Thanks.
Div elements are block elements, unless you specify the display property to inline or inline-block it wont align to to the right like other inline elements do.
adding display : inline-block to the css of div's will give you what you want.
You have two ways to place you blocks horizontally: display property or float property.
It doesn't matter that you have set width to your elements. They are still block and displayed vertically.
To change this behaviour, use stylesheet (note that in both cases width, not max-width should be set):
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
width: 200px;
border: 1px solid red;
display: inline-block;
}
#item2 {
height: 100px;
width: 200px;
border: 1px solid blue;
display: inline-block;
}
or this:
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
width: 200px;
border: 1px solid red;
float: left;
}
#item2 {
height: 100px;
width: 200px;
border: 1px solid blue;
float: left;
}
<div> tag always start with new line if you are not using frameworks like bootstrap or other. If you want to see multiple items in single line then add css like display: inline-block
just add float:left; property in child divs or display:inline-block; https://jsfiddle.net/8tvn0kw6/5/
div is the standard block-level element. A block-level element starts on a new line and stretches out to the left and right as far as it can. Other common block-level elements are p and form, and new in HTML5 are header, footer, section, and more.
Even if you specify width it wont allow other elements right next to it. This the property of block level element.
Use the css inline-block it will occupy the specified width or content width.
https://developer.mozilla.org/en-US/docs/CSS/display
The height of the container should be the sum of heights of the child divs and the heights of the borders of the children
ie., height of parent container = 100+ 100+ 1+ 1+ 1+ 1 = 204px
#container {
height: 204px;
}
The #container ie you div has a display property of block. This is a default property if you don't set it to anything else. In your case the div takes this default display property.
To view #item1 and #item2 side by side just use display: inline-block in your #container.
Please replace your class like below.
#item1{
height:100px;
max-width:200px;
border:1px solid red;
display:inline-block;
}
#item2{
height:100px;
max-width:200px;
border:1px solid blue;
display:inline-block;
}

Center a parent div while width retrieves width value of child div

As the title tells you, I want to center a parent div where the parent div retrieves the width of all its child divs.
This is the code I used to retrieve the width of the child divs:
.parent
{
background-color: yellow;
display: inline-block;
font-size: 0;
/*How could I center this div? I used to do: margin-left: auto; margin-right: auto;
however for this I need to assign a fixed width. I want to assign the width of the
content inside the div.*/
}
.child
{
height: 100px;
width: 100px;
border: 1px solid red;
display: inline-block;
}
Source: http://jsfiddle.net/53me4f8e/
How can I center this div?
Centrally align the text of the parent element, in this case, body. .parent is displayed as an inline-block, which means it behaves like an inline element and is therefore centred:
body{
text-align: center;
}
Note, because text-align is inherited, you may want to revert the text alignment back to left (or right, depending on preference) for .parent:
.parent{
text-align: left;
/* Other styles.. */
}
JSFiddle
This should be:
.parent{
display: block;
text-align:center;
}
updated your fiddle

Inline-block element height issue

I have a simple example in which an outer DIV contains an inner DIV which has
display: inline-block;.
Because I have set the height of the inner div, I expect the outer div to take on the same height as the inner div. Instead, the outer div is slightly taller, as you can see from the fiddle. Question: Why is this happening and how can I "fill up" the outer div without setting its height explicitly?
My goal is to have the outer div expand and shrink based on the height of the inner.
.outer {
background-color: red;
}
.inner {
display: inline-block;
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>
Your .inner div has display: inline-block. That means it needs an inline formatting context around it. Inline layout produces struts, which make room for descenders. You can see how it fits if you put a character next to the .inner element: http://jsfiddle.net/bs14zzeb/6/
The default vertical-align is to have the bottom edge of the inline-block box lined up with the baseline of the surrounding text. Even if there is no surrounding text, the layout engine still has to make room for an entire line of text.
That's why these answers are suggesting that you play with the vertical-align property. Setting it to vertical-align: top, as one answer suggests, tells the layout engine to align the top edge of the inline-block box with the top edge of the line box. Here, since the line height is less than 140px tall, it gets rid of the extra space on the bottom. But if the height of a line is taller than that, you'll still have extra space underneath: http://jsfiddle.net/bs14zzeb/9/
When using inline-block don't forget to set a vertical-align property MDN
.outer {
background-color: red;
}
.inner {
display: inline-block;
vertical-align: top; /* tada!!!! */
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>
Alternatively, use CSS flex:
.outer {
display: flex;
background-color: red;
}
.inner {
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>
The default vertical alignment for inline elements is baseline, so you need to set it to top or middle:
.outer {
background-color: red;
}
.inner {
display: inline-block;
width: 480px;
height: 140px;
background-color: green;
vertical-align:top;
}
<div class="outer">
<div class="inner"></div>
</div>
It's because your #inner has a display property set to inline-block. To fix, change the display to block, or set the vertical-align property to top.
display: inline-block:
.outer {
background-color: red;
}
.inner {
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>
vertical-align: 0:
.outer {
background-color: red;
}
.inner {
display: inline-block;
vertical-align: top;
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>
The problem is the display: inline-block; property. Try display: block; instead.
http://jsfiddle.net/bs14zzeb/7/
.outer {
line-height: 0px;
}
.outer{font-size:0} will do the job
.outer {
background-color: red;
font-size:0
}
.inner {
display: inline-block;
width: 480px;
height: 140px;
background-color: green;
}
<div class="outer">
<div class="inner"></div>
</div>

`margin:auto;` doesn't work on inline-block elements

I have a "container" div to which I gave margin:auto;.
It worked fine as long as I gave it a specific width, but now I changed it to inline-block and margin:auto; stopped working
Old code (works)
#container {
border: 1px solid black;
height: 200px;
width: 200px;
}
.MtopBig {
margin-top: 75px;
}
.center {
margin-left: auto;
margin-right: auto;
text-align: center;
}
<div class="center MtopBig" id="container"></div>
New code (doesn't work)
#container {
border: 1px solid black;
display: inline-block;
padding: 50px;
}
.MtopBig {
margin: 75px auto;
position: relative;
}
.center {
text-align: center;
}
<div class="center MtopBig" id="container"></div>
DEMO fiddle.
It is no longer centered because it now flows on the page in the same way inline elements do (very similarly to img elements). You will have to text-align: center the containing element to center the inline-block div.
#container {
border: 1px solid black;
display: inline-block;
padding: 50px;
}
.MtopBig {
margin: 75px auto;
position: relative;
}
.center {
text-align: center;
}
<div class="center">
<div class="MtopBig" id="container"></div>
</div>
What 'auto' means:
Using auto for the horizontal margin will instruct the element to fill up the available space (source: http://www.hongkiat.com/blog/css-margin-auto/).
Why 'display: inline-block' does not center:
There is no available horizontal space in an inline setting. Before and after it are other inline elements (characters) that take up their own space. Therefore, the element will act as if the horizontal margin is set to zero.
Why 'display: block' centers:
When used as an element with display: block set to it, the available horizontal space will be the full width of the parent element minus the width of the element itself. This makes sense because display: block is reserving this horizontal space (thus making it 'available'). Note that elements with display: block cannot be placed next to each other. The only exception occurs when you use float, but in that case you also get the (expected) zero-margin-behaviour, as this disables the horizontal 'availability'.
Solution for 'inline-block' elements:
Elements with display: inline-block should be approached as characters. Centering characters/text can be done by adding text-align: center to their parent (but you probably knew that already...).
For elements with property display: inline-block;
A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'. [reference: CSS2ยง10.3.9]
margin-left:50%;
transform: translateX(-50%);
.container{
border:solid 1px red;
}
.container img{
display:inline-block;
margin-left:50%;
transform: translateX(-50%);
}
<div class="container">
<img src="https://placekitten.com/100/300" />
</div>