When there is an empty div with contenteditable="true":
CSS:
[contenteditable="true"] {
border: 1px dashed #dedede;
padding: 3px;
}
HTML:
<div contenteditable="true">
<!-- blank by default -->
</div>
In IE and Chrome, it shows the height like a normal input field with small padding. In Firefox, it only shows that 3px padding I added in the styles. W/o that, it collapses and is only as tall as the border.
Do you know if this is a Firefox bug? Can you suggest a way to handle it?
workaround:
[contenteditable='true']:before {
content: "\feff ";
}
CSS2 section 10.6.3:
The element's height is the distance from its top content edge to the first applicable of the following:
the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin does not collapse with the element's bottom margin
the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
zero, otherwise
For this empty div,
1 through 3 are not applicable, since the div is empty. It has no line boxes or children.
Item 4 therefore applies.
The workaround enforces at least one line box inside the div, so that it gets nonzero height.
This works just fine for me in firefox
http://jsfiddle.net/D6D6A/
html:
<div contenteditable='true'></div>
css : changed to black border so easier to see
[contenteditable='true'] {
border: 1px dashed #000;
padding: 3px;
}
notice if you change padding to 0px , it has no height. However, with the 3px padding, it works like it should.
Related
Every html element is a box shape element.
Each box is surrounded by boundaries - padding, border, margin.
--
margin gives white space between two elements.
Why would a box require three boundaries? Would margin that creates white space between any two boxes do not suffice?
Not if you also need a border, or some padding.
Though it is true that both margin and padding create space, there is a difference between where they create space. And that difference is the border.
A border, as the word already implies, is to create a visible border. Padding creates space between said border and the content within. But padding can also be used to create some room around an element when it has a background, for example.
To better illustrate the differences, I'll create a couple of snippets:
This snippet has no border, margin or padding, so no spacing.
.row {
background: red;
}
.column {
background: green;
}
.blue {
background: blue;
}
<div class="row">
<div class="column">
Some text
</div>
<div class="column blue">
Some other text
</div>
</div>
This snippet has margins, giving it some space around the element, which is evident because of the background colors.
.row {
background: red;
}
.column {
margin: 10px;
background: green;
}
.blue {
background: blue;
}
<div class="row">
<div class="column">
Some text
</div>
<div class="column blue">
Some other text
</div>
</div>
This example has both a margin and a border, giving you a wider range of coloring options, as well as more space. Yet, you would be unable to give the different spaces a different color with just a margin.
.row {
background: red;
}
.column {
margin: 10px;
border: 5px solid purple;
background: green;
}
.blue {
background: blue;
}
<div class="row">
<div class="column">
Some text
</div>
<div class="column blue">
Some other text
</div>
</div>
This last example has it all. As you can see, the padding creates space within the box, inside of the border. Added to that, you can also see more of the background color of the element.
.row {
background: red;
}
.column {
margin: 10px;
border: 5px solid purple;
padding: 20px;
background: green;
}
.blue {
background: blue;
}
<div class="row">
<div class="column">
Some text
</div>
<div class="column blue">
Some other text
</div>
</div>
Though you could create just as much space between the elements with margin: 35px; you could not get this (* cough *) beautifully colorful display.
You need a border because sometimes people want a visible border between elements, not white space.
You need padding because people want space between the content and the border and between the border and the next element.
Each one of those properties controls a different aspect of the box.
Margin
The margin clears an area around an element (outside the border). The
margin does not have a background color, and is completely
transparent. The top, right, bottom, and left margin can be changed
independently using separate properties. A shorthand margin property
can also be used, to change all margins at once.
Padding
The padding clears an area around the content (inside the border) of
an element. The padding is affected by the background color of the
element. The top, right, bottom, and left padding can be changed
independently using separate properties. A shorthand padding property
can also be used, to change all paddings at once.
Border
The CSS border properties allow you to specify the style, size, and
color of an element's border.
All three properties together give you great flexibility in styling HTML elements. If you only had margin you would only be able to create space between elements. Plus, padding gives you the ability to create "separation" between elements without collapsing margins.
Here's a good reference for more details: When to use margin vs padding in CSS
Elements don't require to have any of the above. What you see is just an illustration about the box-model of the element which just tells you that there is no margin, padding or border.
Important difference between marginand padding is that margin pushes other elements away from the current element, while padding defines the space between the contents of an element and its' outline.
Border is simply a border. It creates a line as a visual separator between elements, and is not really intended to determine spacing between them.
A good explanation is given on the w3schools website.
Margins and padding have two different uses:
Margin collapse on each other while padding doesn't. Two elements side-by-side, each having margin: 10px will be 10px apart. But if they instead had padding: 10px, the would be 20px apart. Edit I misspoke. I was trying to refer to margin-collapsing, which happens on margin-top and margin-bottom at times. More can be read here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing; and additional discussion here: When to use margin vs padding in CSS
When applying a border, padding will be applied inside the border, pushing it away from the element. Margins are applied outside the border.
Styling such as background-color will be applied to padding, but not to margin.
With margins, negative values are allowed. Not so with padding.
From MDN:
Padding
The padding area extends to the border surrounding the padding. When the content area has a background, color, or image set on it, this will extend into the padding, which is why you can think of the padding as extending the content. The padding is located inside the padding edge, and its dimensions are the padding-box width and the padding-box height.
Margin
The margin area extends the border area with an empty area used to separate the element from its neighbors. It is the area inside the margin edge, and its dimensions are the margin-box width and the margin-box height.
The padding of a textarea is always fixed. When the text content of the textarea is scrolled, the padding remains near the edges.
The padding of a contenteditable element behaves differently. When the text content of the element is scrolled, the padding moves with it.
This demo illustrates the difference.
Can a contenteditable element by styled so its padding behaves more like textarea padding, staying in place while the text content is scrolled?
The answer to your specific question of whether a non-textarea "contenteditable" block level element's padding can behave like a textarea's is "no."
There is likely a way to achieve this look by adding additional elements to your div, but the padding of your div will always behave as padding is designed to.
Your padding issue has nothing to do with the "contenteditable" property. You could take the "cnotenteditable=true" off of your div, and the padding behaves the same way. Padding "clears an area around the content" of the element, which in this example is the text in your div. The padding will always remain around the text, not around the inside of the div.
<style type="text/css">
contenteditable] {
outline: 0px solid transparent;
}
</style>
<body>
<div style="padding:20px">
<div contenteditable="true"></div>
</div>
</body>
A reply in 2019. Set:
border: 10px solid black;
background: black;
color: white;
Works perfectly.
fiddle: https://jsfiddle.net/shill/2k81acux/
I'm testing some css styles on a blog-like div layout. I used div{border: 1px solid black;} to see the divs and look at its positions.
When this line is in my style, it looks right, but I don't want to have the borders (just had it for development).
As soon as I comment it out everything changes it's positions. Why is this so?
JSFiddle Link
div{border: 1px solid black;} /* Comment this to see the problem */
body{ text-align:center; }
.postTabs{
float:left;
background-color: #c8c8c8;
width: 60px;
height: 38px;
padding: 27px 5px 5px 5px;
border-radius: 50%;
}
.postContent{
padding: 15px 15px 15px 50px;
margin-left: 35px;
margin-top: 36px;
text-align: left;
background-color: #a7a7a7;
}
<div class="postContainer">
<div class="postTabs">asdf</div>
<div class="postContent">
<div class="postBody">adf</div>
</div>
</div>
This is because of collapsing margins:
8.3.1 Collapsing margins
In CSS, the adjoining margins of two or more boxes (which might or
might not be siblings) can combine to form a single margin. Margins
that combine this way are said to collapse, and the resulting combined
margin is called a collapsed margin.
Also the spec states:
Two margins are adjoining if and only if:
both belong to in-flow block-level boxes that participate in the same block formatting context
no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for
this purpose.)
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
top margin of a box and top margin of its first in-flow child
bottom margin of box and top margin of its next in-flow following sibling
bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
top and bottom margins of a box that does not establish a new block formatting context and that has zero computed 'min-height', zero
or 'auto' computed 'height', and no in-flow children
In this case, the first child is floated to a side and it is removed from normal flow. Hence the first in-flow child of the .postContainer container is .postContent element which has a margin-top of 36px.
Since the container doesn't establish a block formatting context, and there's no border, padding between them, the margins would be collapsed into one.
You could prevent that by giving the container:
A padding-top of 1px - for instance - Example here.
A border-top of 1px solid transparent Example here.
An overflow of anything other than visible which creates a new block formatting context - Example Here.
For further info you could refer to the spec.
Check the fiddle here
JS Fiddle
it was happening because of float:left for .postTabs class
.postContainer{
clear: both;
float: left;
width: 100%;
}
This is because of the default box model in CSS. The element is as wide as the width, plus any padding, plus any border.
You may have expected the border to sit inside of the element, but it actually makes it wider (by 2px in your case) and taller (again by 2px).
You can adjust your width and height accordingly, or you can change the box-model being used with the CSS box-sizing: border-box;
In your case, though, you are only applying the border for development purposes, so changing your CSS to support the border will mean changing it all back again later.
Rather than do all that work, use your browser tools. The screenshot below shows the browser tools in Firefox (all browser have similar tools to this). When you highlight the element in the HTML shown in the tools, it shows the outline of the element on the actual page.
This gives you your development view whenever you need it without having to change the code.
Came across something very curious today I can't figure out the reason for.
For this HTML:
<div class="a"><div class="b"></div></div>
And CSS:
.a {
background: blue;
}
.b {
display:inline-block;
height: 30px;
width: 30px;
background: red;
}
I would expect the outer "a" div to be just as tall as is needed to contain "b", 30px tall. But when rendered "a" is 35px tall. There are 5 pixels of emptiness below "b". Why?
See http://jsfiddle.net/Pb2q9/
I've tried this on Chrome and Firefox and they both give the same output.
Curiously if you change "b" to be display:block that extra space at the bottom goes away. Can anyone explain why these two scenarios render differently? What is it about inline-block that dictates that 5px of space should exist?
EDIT:
Stranger still I found that if you change the HTML to
<div class="a"><div class="b">x</div></div>
Note the single "x" character in the b div the extra 5px at the bottom goes away!
The vertical white space you see is due to the line-height property in play. If you set line-height: 0 on the parent element, you can see that the spacing goes away - http://jsfiddle.net/Pb2q9/9/
When working with inline-block elements and yet wanting to achieve the layout behavior of block-level elements, remember to set both font-size and line-height to 0.
It is a normal behaviour of inline block elements. There is always white space.
If you want to remove white space of element, change fontsize of parent container to 0px
.a{font-size:0px;}
.b{font-size:16px;}
Fiddle
This might be due to margin collapsing and I know about margin collapsing, at least how it affects adjacent elements, but I don't understand how it works on nested elements when negative margins are involved.
For example, in this markup and accompanying CSS:
Markup
<div class="parent">
<div class="child">
Child 1
</div>
</div>
<div class="parent">
<div class="child negative">
Child 1
</div>
</div>
CSS
body {
background: white;
padding: 45px;
}
.parent {
border: 1px solid black;
margin-bottom: 10px;
}
.negative {
margin-bottom: -1px;
}
Live example here.
When I inspect the height of the second .parent div, I notice it is 1 pixel less than the first one. This has happened because of the negative margin on the .negative element inside it. I had a quick look at W3C and couldn't find an explanation for this behavior.
Could someone please explain what's happening here and also provide me with a link to the W3C spec section about it?
This might be due to margin collapsing and I know about margin collapsing, at least how it affects adjacent elements, but I don't understand how it works on nested elements when negative margins are involved.
Section 8.3.1 has all the details. It also covers the behavior of adjoining margins between nested boxes, as well as negative margins.
However, what you're seeing here is not the effect of margin collapse because you have negated it with a border: 1px solid black declaration in your .parent rule. That means having a border there prevents your .parent margin from collapsing with your .child.negative margin altogether.
Rather, this is simply how negative margins work. This is covered in various sections of the visual formatting model, but it's most succinctly and directly addressed in the beginning of Section 11, which summarizes it thus:
Generally, the content of a block box is confined to the content edges of the box. In certain cases, a box may overflow, meaning its content lies partly or entirely outside of the box, e.g.:
...
A descendant box has negative margins, causing it to be positioned partly outside the box.
So what's happening here, instead, is:
The absolute value of the .child.negative element's negative margin is subtracted from the .parent element's actual height (by 1px).
As a result, the .child.negative element itself overflows .parent (because its own height is not changed and the default overflow for any div is visible).
Since margin collapse does not take effect here, the margin-bottom: 10px in your .parent is unaffected. Note that while any subsequent elements in normal flow will be shifted up by 1px, this is mainly due to the negative margin of your .child.negative element; in other words, a side effect of step 1.
And that's all there is to it.
when you are using .negative { margin-bottom: -1px; } then it will moved at the top. see this example.
please refer the following link you understand easily.
http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/
body {
background: white;
padding: 45px;
}
.parent {
border: 1px solid black;
margin-bottom: 10px;
min-height: 30px;
}
.negative {
margin-bottom: 20px;
}
conclusion:
For e.g. In your case i have to added min-height:30px to parent class so that it remains fix. if moved only if you add positive margins to negative class. It just because you can see results in above figure that tells all what you need is.
see the cssdesk link click here cssdesk
Hope, it will helps you. Cheers. !!
Margins of first and last elements will apply to outer element when the outer element doesn't have border, padding and content, instead of it self.
In your case, parent node has border, so margin collapsing won't apply in this case. As you have margin-bottom = -1px for the child node inside, when calculate the outer height of the child node will be the height of its content + padding + border-width + margin. So it will be 1px less when measuring from outside. That's why the height of parent node will be 1px less than the upper example. To see it more clearly, you may apply a background to the child node, say yellow, you will find that the child node will overlap the border of the parent node.
But if you remove the border of the parent node, it will be a total different situation.
For instance to explain margin collapsing, say you have
<div style="background-color:black">
<div style="height:10px; background-color:white; margin-top: 10px"></div>
</div>
You will not see a black box of 10px height, as the outer node will be considered to have a 10px margin on top, and the inner one's margin is ignored. And for negative situation, the outer margin will decrease.
Quote from spec:
When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins' widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.
For more info:
https://developer.mozilla.org/en-US/docs/CSS/margin_collapsing