Strange behavior regarding inline-block elements and margins within a container - html

Here is the jsfiddle
In my example, giving either of the children elements a bottom margin causes its sibling to be pushed down by whatever margin I specify; I hadn't anticipated seeing anything move since the container is larger than each div. Why is this the case?
HTML
<div class=container>
<section></section>
<aside></aside>
</div>
CSS
.container {
background: whitesmoke;
height: 12em;
width: 12em;
}
.container section {
background: slategray;
display: inline-block;
height: 04em;
margin-bottom: 20px;
width: 04em;
}
.container aside {
background: gold;
display: inline-block;
height: 04em;
width: 04em;
}

Add vertical-align: top to your section element. As these elements are ìnline-block, they are not simply behaving as boxes anymore - they have flowing text properties. It is not really the margin that is pushing down the other element, it is the default vertical-align property they have.
jsFiddle Demo
Other Demo that shows the effect with text - the key is vertical-align

Related

How to center elements that have float inside one <div>?

I need to fix a problem on an existing web page, I need to center elements that have float : left; inside one big <div>. I don't want to remove the floating, and I'm wondering what is the best way to center those elements and make them on two rows.
.big {
width: 150px;
height: 150px;
background: gold;
}
.a {
margin: 5px;
width: 50px;
height: 20px;
text-align: center;
float: left;
background-color: red;
}
<div class="big">
<div class="a">1</div>
<div class="a">2</div>
<div class="a">3</div>
<div class="a">4</div>
</div>
Floating makes this weird. Otherwise
.big{
width:150px;
height: 150px;
background: gold;
text-align: center;
}
.a{
display: inline-block;
margin: 5px auto;
width:50px;
height:20px;
text-align: center;
background-color:red;
}
<div class="big">
<div class="a">1
</div>
<div class="a">2
</div>
<div class="a">3
</div>
<div class="a">4
</div>
</div>
You may use flexbox.
.big{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
background: gold;
width: 150px;
height: 150px;
}
.a {
flex: 0 0 35%;
margin: 5px;
width: 50px;
height: 20px;
text-align: center;
float: left;
background-color: red;
}
<div class="big">
<div class="a">1
</div>
<div class="a">2
</div>
<div class="a">3
</div>
<div class="a">4
</div>
</div>
I do not believe there is a point in floating if you do have no intention of wanting to float to the top and to the left. You need to master the use of both position and display properties. This I believe is what you are looking for. I have put explanations underneath explaining what the relevant display and position properties, as well as why I used what I did.
.big {
width: 150px;
height: 150px;
background: gold;
}
.a {
position: relative;
left: 12px;
display:inline-block;
margin: 5px;
width: 50px;
height: 20px;
text-align: center;
background-color: red;
}
Positioning is how the element is positioned in the document. The options in CSS are either static, relative, absolute, fixed.
Static: This is the browser default. It is not affected by positioning, and will just be positioned in the natural flow of the page.
Relative: Will cause element to be positioned relative to it's initial position. (i.e.: if the element is positioned at X (initial position), then will be moved depending on what properties put in)
Absolute: Will cause element to be positioned relative to next parent element. An important thing to note about this is that elements are removed from the flow of the page meaning that it is possible to have multiple elements stack on top of one another.
Fixed: Will cause element to be fixed relative to the browser window, commonly known as viewport itself. If you scroll down, the position will be fixed, hence the name.
Display
This is how the browser will treat the type of "box"/element that is used (all elements can be considered boxes, as per the box model).If you have trouble grasping the concept, put element {border: solid black} into all your css elements and you'll see what I mean.
There are multiple displays will only get into the 3 of the arguably most important ones: block, inline, inline-block.
Block: element will take up the maximum amount of horizontal space necessary. Think of the li as an example. The list point will take up the maximum amount of horizontal space, and thus each separate li can be considered a block.
Inline: element will take up the minimum amount of horizontal, and vertical space necessary to fit within the flow. Think of the anchor a tag, as it will take up the minimum amount of space necessary to fit within the flow of a paragraph.
Inline-block: Considered an inline value but with the ability to change the width and height of the element.
For your example, I have used the relative positioning element (positioned it right 12px relative to where it originally was) and changed the display to be inline-block, as divs are naturally block elements and thus, without the inline-block display feature, they would have only stacked 1 at a time.

Why this trick centers text vertically in dynamic height div (and why it breaks)?

I found this stackoverflow answer very interesting. It works to vertically center text of any length in a div of any height. Basically it uses a empty <span> tag directly in front of the node containing text, and
HTML:
<div>
<span></span><p>This is really really long text but it will be centered vertically.</p>
</div>​
CSS:
div {
background: yellow;
color: red;
width: 200px;
text-align: center; /* horizontally center */
height: 300px; /* any height */
padding: 0 20px
}
div span:first-child {
height: 100%;
vertical-align: middle;
display: inline-block;
}
div p {
margin: 0;
vertical-align: middle;
display: inline-block;
}
Also even more interesting is if you separate closing span tag (</span>) and opening paragraph tag (<p>) on two separate lines, or if you add a whitespace between the two, the trick breaks.
My question is - how does this trick work? How is span helping center the text? And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
I have created a fiddle to demonstrate both points: https://jsfiddle.net/axRxE/385/
My question is - how does this trick work? How is span helping center the text?
Since you give the span inline-block property, the span then inherits it's parent height (with height: 100%) - which in you example is a fixed 300px. And since you gave also the same property to the paragraph, those two elements are one next to each other. See an example:
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And you also put vertical-align: middle (which works with inline-block) on both of them, which gives them that align (you only need to add that property to the larger one):
#parent {
height: 300px;
}
span {
height: 100%;
display: inline-block;
/* some width and background-color for demonstration */
width: 5px;
background-color: red;
/* added vertical-align */
vertical-align: middle;
}
p {
margin: 0;
display: inline-block;
}
<div id="parent">
<span></span>
<p>foobar</p>
</div>
And why does it break when a newline/whitespace is added in HTML between closing </span> tag and opening <p> tag?
That's simple - when you use inline-block there is always a whitespace issue between them. And since you didn't add some width to the paragraph, it takes all the width it can take, and with that additional width from the whitespace, the paragraph goes below the span.
In your example, your parent has 120px width, the span uses 0px, so the paragraph takes all of the parents width, which is 120px. Now, with the additional whitespace (which is ~ 4px), since she paragraph uses all the width, the whitespace doesn't fit so the paragraph "breaks" - it goes below the span.
Also check:
inline-block element with no text renders differently
Vertical-Align: All You Need To
Know.

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

Float-left disabled padding

Two divs are side by side, one is floating left with a width of 25%, the other just has a width of 75%. But when padding is applied on the right hand div, the padding doesn't work properly.
Here is a JSfiddle example:
http://jsfiddle.net/88upt/
<div id="top">
</div>
<div id="middle">
</div>
<div id="bottom">
</div>
CSS
#top {
float: left;
background-color: green;
width: 25%;
height: 100%;
}
#middle {
background-color: blue;
padding: 30px;
min-height: 30%;
}
#bottom {
background-color: red;
min-height: 70%;
}
Can someone explain to me why this is happening?
Thanks
Floating something is kind of like making it's position absolute. It will hover on top of it's neighboring containers. Add a margin-left equal to the width of the floated element to make the container the correct width.
http://jsfiddle.net/88upt/4/
#middle {
background-color: blue;
padding: 30px;
min-height: 30%;
margin-left:25%
}
EDIT Elaborating a bit more.
The floated element pushes the content of the sibling elements over. It will not push the left side of the content's element over. The padding is there it's just hidden by the floating element.
Add overflow = "auto" in the #middle.
#middle {
background-color: blue;
padding: 30px;
min-height: 30%;
overflow: auto;
}
In this way, you don't need to know the width of floating element.
Width doesn't factor in padding.
Source: http://www.w3schools.com/css/css_boxmodel.asp
The width only applies to content, not padding, border, or margin.
You can find more information here.

Firefox: parent does not feel dynamic content width

Example
If the adjacent element of a parent floating, the parent does not feel the width of the element, if it is dynamic. In chrome and opera works fine.
<div class="b-wrap">
<div class="b-content">
<div class="b-rect-left"></div>
<div class="b-rect-right"></div>
<div class="b-child-cont">джигурдаололо</div>
</div>
</div>
.b-wrap {
background-color: red;
height: 50px;
float: left;
}
.b-content {
margin: 5px;
overflow: hidden;
}
.b-rect-left {
width: 40px;
height: 40px;
float: left;
background-color: orange;
}
.b-rect-right {
width: 30px;
height: 30px;
float: right;
background-color: green;
}
.b-child-cont {
overflow: hidden;
}
Firefox calculated the width of an element that contains floats differently from Chrome. I don't know why.
However, what seems to be happening is the following.
The actual content in your snippet is in b-child-cont, a non-floated element. b-child-cont determines the width of b-content since the two other elements are (b-rect-left and b-rect-right) are floated and do not factor into determining the width of the content. In turn, the width of b-content sets the width of b-wrap, because b-wrap is floated and takes on the width of its child elements.
You as a designer and developer, need to allow some space for the two floated elements. You can do this in many ways. I will give two examples.
(1) Add left and right margins to b-child-cont:
.b-child-cont {
overflow: hidden;
background-color: yellow;
margin-left: 40px;
margin-right: 30px;
}
(Note: I added a background color to show the extend of the element.) The 40px and 30px values are based on the widths of the left and right square elements respectively.
(2) You can also specify a with to the parent element containing the floats:
.b-child-cont {
overflow: hidden;
background-color: yellow;
text-align: center;
}
.b-content {
width: 30em;
}
In this case, I set the with of b-content to 30em (you can adjust this accordingly) and I centered the text in b-child-cont.
You have come across a cross-browser discrepancy in how the CSS box model is calculated. Once you are aware of it, you need to design around it, but that is not too hard to do.
Fiddle Reference: http://jsfiddle.net/audetwebdesign/dzK73
Just add this firefox exception
#-moz-document url-prefix() {
.b-wrap{width:175px;}
}