css relative positioning breaks div into new line - html

I have the following fiddle for this question: http://jsfiddle.net/jcb9xm44/
There are 2 inline-block div's in a parent div:
<div class="outer">
<div class="inner1">
Y
</div>
<div class="inner2">
X
</div>
</div>
The css assigns a width to the parent div and 2 widths to the child div's.
.outer {
width: 210px;
border: 1px solid red;
}
.inner1 {
width: 200px;
border: 1px solid orange;
display: inline-block;
}
.inner2 {
width: 50px;
position:relative;
left: -50x;
display: inline-block;
border: 1px solid lightblue;}
I was expecting that both divs appear on the same line. Although the parent is not wide enough to hold both children, since the second child has a negative offset, it should be possible to fit them both on the same line. Why does it break the line?

Why does it break the line?
As you stated, it's because the parent element isn't wide enough for both elements. To change this behavior, you could add white-space: nowrap to the parent element in order to prevent the inline-block elements from wrapping.
Example Here
.outer {
width: 210px;
border: 1px solid red;
position:relative;
white-space: nowrap;
}
Side notes:
You had a typo - left: -50x -> left: -50px.
inline elements respect whitespace in the markup.
The element's border is included in its width calculations. Use box-sizing: border-box to include it.
You could alternatively use margin-left: -50px as Mary Melody pointed out.

Related

Why the CSS's overflow property clear float?

I tried the next code:
div.a {
position: relative;
width: auto;
height: auto;
border: 3px solid #73AD21;
}
div.b {
float: right;
width: 200px;
height: 100px;
border: 3px solid #73AD21;
}
<div class="a">The outer box;
<div class="b">The inner box</div>
</div>
But for some reason, when I use float instead of another way of positioning, then the outer box become to be with small height, and the inner box flows out of the outer box.
When I asked my friend, then he told me to add the property overflow: hidden; to the outer box.
It worked, and the outer box streched enough to contain the inner box.
When I learned about this property, I learned that the porpose of this, is to show\disappear etc scroll bar.
Somebosy can please explain me the aother thing about overflow I didnt understood?
Quoting from Block formatting contexts
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
According to the above quoted text and what I understand,
overflow:hidden causes a new float context, which clears the float from the child elements which are floating. Hence the parent auto adjusts.
It would be similar to clearing the parent like this:
#parent:after {
content: "";
display:table;
clear: both;
}
Example with manual clearing the parent:
div.a {
position: relative;
width: auto;
height: auto;
border: 3px solid #73AD21;
}
div.b {
float: right;
width: 200px;
height: 100px;
border: 3px solid #73AD21;
}
div.a:after {
content: "";
display: table;
clear: both;
}
<div class="a">The outer box;
<div class="b">The inner box</div>
</div>
You are using float but not clearing. Use following code it will works
First Option
<div class="a">The outer box;
<div class="b">The inner box</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
div.a {
position: relative;
width: auto;
height: auto;
border: 3px solid #73AD21;
}
div.b {
float: right;
width: 200px;
height: 100px;
border: 3px solid #73AD21;
}
.clear {
clear:both;
}
Second Option
<div class="a">The outer box;
<div class="b">The inner box</div>
</div>
div.a {
position: relative;
width: auto;
height: auto;
border: 3px solid #73AD21;
}
div.b {
float: right;
width: 200px;
height: 100px;
border: 3px solid #73AD21;
}
div.a:after,div.b:after {
content"";
display:block;
clear:both;
}

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;
}

In CSS, the "margin" of element has no effect for the "height" of its parent?

Following is the snippet (demo on JSFiddle)
#inner {
background-color: yellow;
margin-left: 50px;
margin-bottom: 50px;
}
#outer {
background-color: red;
}
<div id="outer">
<div id="inner">
test
</div>
</div>
As can be seen in the demo, the #inner element has a margin-bottom.
I expected the height of #outer will be large enough to include the outline of #inner margin. And the output will have a red bar below the yellow bar.
However, I found the #outer's height is not changed at all though I added the rule margin-bottom: 50px for #inner.
Does anyone have ideas about this? And is there a way to ensure the content area of parent is large enough to hold the outline of its child's margin?
Also, apart from giving a hack solution, it would be great if the answer can include some explanation or links to related document/article. And why is the margin rule designed like this.
Thanks!
What you are seeing is the collapsing margins problem.
Top and bottom margins of blocks are sometimes combined (collapsed)
into a single margin whose size is the largest of the margins combined
into it, a behavior known as margin collapsing.
Out of the three cases, yours is the case of collapsing margins between parent and child elements.
If there is no border, padding, inline content, height, min-height, or
max-height to separate the margin-bottom of a block with the
margin-bottom of its last child, then those margins collapse. The
collapsed margin ends up outside the parent.
If you add another element just after your parent div you will see that the margin ends up outside of it. The snippet below, shows you the collapsed margin:
#inner { background-color: yellow; margin-left: 50px; margin-bottom: 50px; }
#outer { background-color: red; }
<div id="outer">
<div id="inner">
test
</div>
</div>
<p>You can see the collapsed margin above this text outside of the parent div.</p>
Here is the reference from the specs: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
How to fix this?
The solution is given in the quoted ref text itself above. Just apply any one of these to your parent div - border, padding, height, min-height, or max-height.
Easiest way to fix this would be to add a border to your outer div:
#outer { background-color: red; border: 1px solid gray; }
Better still, apply padding to the parent div instead of the margin on inner one.
#outer { background-color: red; padding-bottom: 50px; }
Examples:
Fiddle (with border): http://jsfiddle.net/abhitalks/rrtfhyky/1/
Fiddle (with padding): http://jsfiddle.net/abhitalks/rrtfhyky/2/
Snippet (with padding):
#inner { background-color: yellow; margin-left: 50px; }
#outer { background-color: red; padding-bottom: 50px; }
<div id="outer">
<div id="inner">
test
</div>
</div>
<p>Some text that follows.</p>
I had the same problem, just add overflow: auto to #outher div and it will fix the parents height
#inner {
background-color: yellow;
margin-left: 50px;
margin-bottom: 50px;
}
#outer {
overflow: auto; /* ADDED */
background-color: red;
}
<div id="outer">
<div id="inner">
test
</div>
</div>
Add This CSS
#inner {
background-color: yellow;
margin-left: 50px;
margin-bottom: 50px;
display: inline-block;
}
give a border to outer div :
#inner {
background-color: yellow;
margin-left: 80px;
margin-bottom: 50px;
}
#outer {
background-color: red;
border:1px solid white;
}
<div id="outer">
<div id="inner">
test
</div>
</div>
I know this common "bug", what I would do if I were you is changing the margin into padding and put it to the outer div:
My solution:
#inner {
background-color: yellow;
}
#outer {
background-color: red;
padding-left: 50px;
padding-bottom: 50px;
}
Also there are 3 other possible fixes:
By #Jenti Dabhi is the add the display:inline-block to the #inner div:
#inner {
background-color: yellow;
margin-left: 50px;
margin-bottom: 50px;
display: inline-block;
}
By #Chris is to add overflow: auto to the #outer div:
#outer {
overflow: auto;
background-color: red;
}
By #Abhitalks is to add a border to your #outer div:
#outer {
background-color: red; border: 1px solid gray;
}
This is a Typography concept,
generally, vertical margins of adjacent elements collapse!
Have a look at this article

CSS - div height

I am getting a little gap between child-div and its parent-div. Is it possible for child-div to on its parent-div height? or (the way around)possible if the parent-div can scope the height of its child-div for not to overlap or get some extra spaces.
I have a DOM like this:
<div class="parent-div">
<div class="parent-image">
</div>
<div class="child-div">
</div>
</div>
here is my CSS:
.parent-image:{
height:60px;
}
.parent-div{
border: 1px solid #E3E3E3;
border-radius: 4px 4px 4px 4px;
margin-bottom: 20px;
width: 100%;
}
.child-div{
????
}
If you specify height: 100%; it will take the height of the parent.
If your child has padding, you need to change its box-sizing.
.child {
padding: 10px;
box-sizing: border-box;
}
If your child has more content than the parent, you either need to tell it to scroll, or hide. Note that on some browsers the scroll-bar will be inside the div, and on other browsers, it'll be on the outside.
.parent.c .child {
overflow: auto;
}
or
.parent.d .child {
overflow: hidden;
}
Demo of All
In your CSS, you can set your child-div to:
.child-div{
height:100%;
}
Here is a demonstration: http://jsfiddle.net/Xq7zQ/