element following emty inline-block div has strange padding at top [duplicate] - html

This question already has answers here:
Why is this inline-block element pushed downward?
(8 answers)
Closed 8 years ago.
I'm wondering myself, why an empty div, that has the display:inline-block style behaves differently from a div that cointains text. It somehow seems to add some top-padding to following elements, that cannot be removed.
HTML
<p>
<div class="a">A</div><div class="b">B</div>
</p>
<p>
<div class="a"></div><div class="b">B</div>
</p>
CSS
.a {
width:20px;
height:20px;
display:inline-block;
background-color:red;
}
.b {
background-color:orange;
line-height:20px;
font-size:12px;
display:inline-block;
}
Output
There's also a fiddle
Can someone explain this behavior?

inline elements are vertical-align: baseline by default. The baseline is affected by the text.
Change to vertical-align: top / middle / bottom
From the MDN:
baseline
Aligns the baseline of the element with the baseline of its parent. The baseline of some replaced elements, like <textarea> is not specified by the HTML specification, meaning that their behavior with this keyword may change from one browser to the other.
Your new example
.a {
width: 20px;
height: 20px;
display: inline-block;
background-color: red;
vertical-align: top;
}
.b {
background-color: orange;
line-height: 20px;
font-size: 12px;
display: inline-block;
vertical-align: top;
}
br {
line-height: 2;
}
<div class="a">A</div>
<div class="b">B</div>
<br />
<div class="a"></div>
<div class="b">B</div>

Related

How to prevent text inside a div from affecting the spacing around div [duplicate]

This question already has answers here:
Align inline-block DIVs to top of container element
(5 answers)
Why is this inline-block element pushed downward?
(8 answers)
Closed 1 year ago.
<style>
#main {
width: 110px;
height: 110px;
}
#main div {
width:50px;
height: 50px;
border: 1px solid black;
display: inline-block;
}
</style>
<div id='main'>
<div>x</div>
<div>x</div>
<div>x</div>
<div></div>
</div>
I have a grid of divs set up just a like a checker board. The divs are either empty, or have a single unicode character inside of them.
When a character is removed from or added to the div, the spacing around the div is affected. (see snippet)
How can I stop this behavior? I would like for the content inside of the div to not affect the positioning or spacing around the div.
you can fix your code by adding vertical-align:top to your inner 4 divs
Don't use the display:inline-block, try with display:flex on the outer div.
Basic concepts of flexbox
This issue occurs because of the way that vertical-align is calculated. When no vertical-align is set, the default is baseline. However, when there is no text, baseline is calculated differently. See this answer.
Using FlexBox, as suggested by most of the other answers would obviously avoid this issue.
If you want to avoid FlexBox, probably the best option is to just set vertical-align explicitly, as suggested in DCR's answer.
Another method would be to wrap the inner text in a <span> and add position: absolute. This way, all the boxes effectively have the same size content, and the discrepancy is resolved. Here's an example:
<style>
#main {
width: 110px;
height: 110px;
}
#main div {
position:relative;
width:50px;
height: 50px;
border: 1px solid black;
display: inline-block;
}
#main div span {
position: absolute
}
</style>
<div id='main'>
<div><span>x</span></div>
<div><span>x</span></div>
<div><span>x</span></div>
<div><span></span></div>
</div>
Like Nicola Revelant said in their answer, you can use something like flexbox to make this work. Here's an example:
<style>
#main {
width: 110px;
height: 110px;
display: flex;
}
#main div {
display: flex;
flex-direction: column;
}
#main div div {
width: 50px;
height: 50px;
border: solid 1px black;
}
</style>
<div id='main'>
<div class="row1">
<div>x</div>
<div>x</div>
</div>
<div class="row2">
<div></div>
<div></div>
</div>
</div>

Why vertical-align does not work in this specific example

Why does Vertical-align not work on the element I am trying to align? But works if I align other elements around it?
I have read few articles on vertical align, which state that it was created to align tables or inline elements.
Hence I set all my elements as inline-block, in the code.
When I try to vertical-align the menu links, it does relatively nothing.
If I try to align 1 box to the left or right of menu links it will push down the menu.
But if I vertical-align both boxes at once, the text gets aligned.
What does this happen, how am I supposed to use vertical-align, or am I not supposed to use it anymore?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FlexPractice</title>
<link rel="stylesheet" href="practiceflex.css">
</head>
<body>
<nav class="container">
<div class="logo">
<div class="box" id="box1"> </div>
</div>
<div class="menu">
<ul>
<li>Home</li>
<li>Our mission</li>
<li>Services</li>
<li>About Us</li>
<li>Leave a comment</li>
</ul>
</div>
<div class="profilepic">
<div class="box" id="box2"> </div>
</div>
</nav>
</body>
</html>
html,body{
padding:0px;
margin:0px;
}
.box{
width: 48px;
height:50px;
background: red;
}
.menu > ul > li{
text-decoration: none;
display:inline;
margin-right:20px;
}
.container
{
display:inline-block;
/* vertical-align: middle;*/
}
.container * {
display:inline-block;
/* vertical-align: middle;*/
}
/*
#box1{
vertical-align: middle;
}
#box2{
vertical-align: middle;
}*/
https://jsfiddle.net/curiousproger/gurmL8f9/
Refer to MDN docs vertical-align. One use case is indeed for table-cells, the other is, as stated on MDN:
To vertically align an inline element's box inside its containing line box (emphasis mine)
This means 2 things:
vertical-align will only affect elements with display: inline or display: inline-block
the line-height property of the parent, and of any children may greatly influence the resulting alignments of all elements involved.
With extra levels of nesting, line-height being important for text alignment and line breaks, vertical-align is best used for inline content like paragraph text, images, icons, footnote references etc. For vertically centering block-level elements (like a navigation) it is much safer to use display: flex; align-items: center; on the parent
For illustration purposes of potential problems I included some test cases below.
[id^="case"] { border: 1px solid; height: 50px; }
code { display: inline-block; }
.box {
display: inline-block;
width: 32px;
height: 32px;
background: red;
vertical-align: middle;
}
#case-2, #case-3 {
line-height: 50px;
}
#case-3 code {
line-height: 100px;
vertical-align: middle;
}
#case-3 .box {
line-height: 20px;
vertical-align: middle;
}
<h2>vertical-align tests</h2>
<div id="case-1">
<span class="box"></span>
<code>#case-1</code>
<span class="box"></span>
</div>
<div id="case-2">
<span class="box"></span>
<code>#case-2</code>
<span class="box"></span>
</div>
<div id="case-3" style="line-height: 0;">
<span class="box"></span>
<code>#case-3</code>
<span class="box"></span>
</div>
<h2>Flexbox</h2>
<div id="case-4" style="display: flex; align-items: center;">
<span class="box"></span>
<code>#case-3</code>
<span class="box"></span>
</div>
The vertical alignment default setting (i.e. if you don't define anything else) is baseline, which is the baseline of the last line of text inside an element. If there is no text, it's the bottom border instead.
In this variation of your fiddle the first box (no text) is aligned to the baseline of the text elements by its bottom border, in the other box (containing text now) the last text line is aligned to the other text elements:
https://jsfiddle.net/x3q0v5ab/
Note: I didn't change the CSS, i only put some text into the second block.
So if you use a vertical-align setting other than baseline, use the same on both blocks.

DIV not fitting one inside the other as expected [duplicate]

This question already has answers here:
Floating elements within a div, floats outside of div. Why?
(11 answers)
Closed 6 years ago.
I am faced with a CSS problem. The situation is as follow:
I have this kind of structure:
#Block {
background-color: #FF0000;
padding-top: 30px;
padding-bottom: 30px;
padding-left: 30px;
padding-right: 30px;
}
[class="Element"] {
width: 33.33%;
background-color: #0000FF;
float: left;
}
<div id="Block">
<div class="Element">
Some contents.
</div>
<div class="Element">
Some more contents.
</div>
<div class="Element">
Still some more contents.
</div>
</div>
I was expecting to see a red box behind my 3 elements(blue), containing them.
But I only see a red rectangle behind the elements, but with the wrong size, more precisely not high enough. It seems that the Block part is totally un related to the rest.
What did I do wrong?
Clear the floats using this:
#Block:after{
content:'';
display:block;
clear:both;
}
and I guess that looks OK now.
Why this happens?
If the containing blocks have floating elements, then it will get height only if you clear the floating context.(See an example here)
If any one of them are not floated, then the containing block takes the height of this element.
You can also use overflow: hidden on the containing block to get the same effect.
#Block {
background-color: #FF0000;
padding-top: 30px;
padding-bottom: 30px;
padding-left: 30px;
padding-right: 30px;
}
[class="Element"] {
width: 33.33%;
background-color: #0000FF;
float: left;
}
#Block:after{
content:'';
display:block;
clear:both;
}
<div id="Block">
<div class="Element">
Some contents.
</div>
<div class="Element">
Some more contents.
</div>
<div class="Element">
Still some more contents.
</div>
</div>

How do I align div elements where some have text and some don't?

I am trying to have a series of inline-block div elements inside a parent block div element all sit at the same height. Some of the divs have text in them and others do not. The text in the divs needs to be vertically centered but not horizontally. I used line-height to center the text, but the div with no text does not align with the others. Here is my code:
<div class='line'>
<div class='someText'>text 1</div>
<div class='someText'>text 2</div>
<div class='noText'></div>
<div class='someText'>text 3</div>
<div class='someText'>text 4</div>
</div>
.line{
display: block;
height: 50px;
max-height: 50px;
}
.someText{
display: inline-block;
line-height: 50px;
background-color: RED;
padding: 10px;
}
.noText {
display: inline-block;
height: 50px;
width:50px;
background-color: BLUE;
padding: 10px;
}
Could anyone explain to me why this is happening and/or give a possible solution? I would like to avoid using tables if possible.
Thanks!
Also here is a jsfiddle showing the problem. https://jsfiddle.net/n1LbcLr1/
I found the answer here: Why does setting line-height for one of two inline-block sibling divs effect both divs?
You can simply add vertical-align: top; to the divs with text.
Blue div positioned itself at the text baseline. If you change vertical-align to top it will position itself correctly.

Horizontally align three elements on center, left and right in the same row/line

We have one container with three child elements:
<div class="container">
<div class="box-a">some content</div>
<div class="box-b">other content</div>
<div class="box-c">some other content</div>
</div>
We want to avoid using floats, and we'd like to align box-a on the left part of the page, box-b on the center, and box-c on the right part of the page.
All three child elements could have some padding/margin and a background color.
So far, we've used display: inline-block, but as the text-align should be set in the "container" element, we can only choose one method of alignment.
http://codepen.io/anon/pen/RNwLJK here's how it looks
You can use the inline-block porperty and also the text-align with the value justify. Try this:
.container {
text-align:justify;
}
.container > div {
display:inline-block;
}
But in order to make it work you need a little fix with a pseudo-element:
.container:after {
content:" ";
display:inline-block;
width:100%;
}
Check the Snippet Below
.container {
text-align: justify;
}
.container > div {
display: inline-block;
line-height: 30px;
padding: 0 10px;
background: #000;
color: #fff;
}
.container:after {
content: " ";
display: inline-block;
width: 100%;
}
<div class="container">
<div class="box-a">some content</div>
<div class="box-b">other content</div>
<div class="box-c">some other content</div>
</div>
Note: you need to have an empty space between the inline-block elements on the HTML markup, otherwise this won't work. Some builders/CMS systems minify the HTML so this makes all three elements count as one word therefore text-align justify doesn't work.