Why the child element does not take margin relative to parent [duplicate] - html

This question already has answers here:
How do nested vertical margin collapses work?
(3 answers)
Closed 6 years ago.
I am providing the child <p> inside a <div> element a margin, but it is shifting the div element itself. I want to shift down the paragraph to an arbitrary value. I know we can provide padding to parent element, but what about it?
Here, take this example code... Try changing the .square p margin property.
*{
margin: 20px auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.square {
width: 100px;
height: 100px;
background: #f56;
} .square p {
margin: 50px auto;
}
<div class="square"><p>Hi</p></div>
Shouldn't it be relative to the parent element?

p is a block element and this behaviour is expected as the parent square is too.
Try inline-block display for the p tag and you can adjust margins relative the parent. If you want to keep p as a block, you should be giving overflow: hidden for the parent.
Example using inline-block:
*{
margin: 20px auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.square {
width: 100px;
height: 100px;
background: #f56;
} .square p {
margin: 50px auto;
display: inline-block;
}
<div class="square"><p>Hi</p></div>

The problem here is parent-child margin collapsing . One way to fix it is to use overflow: hidden
* {
margin: 20px auto;
box-sizing: border-box;
}
.square {
width: 100px;
height: 100px;
background: #f56;
overflow: hidden;
}
.square p {
margin: 50px auto;
}
<div class="square">
<p>Hi</p>
</div>

You should give display:inline-block; property to child p.
*{
margin: 20px auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.square {
width: 100px;
height: 100px;
background: #f56;
}
.square p {
margin: 50px auto;
display: inline-block;
}
<div class="square"><p>Hi</p></div>

Related

How do I align 2 divs (each has its own padding) next to each other?

With the padding commented out as shown, the website works like I'd expect (2 div columns next to each other.
However, when I add padding, the #right div shifts downwards. How would I make it work as intended with padding?
HTML: Two divs contained directly in body
CSS:
#left {
background-color: green;
float: left;
margin-top: 0px;
width: 70%;
}
#right {
background-color: blue;
float: right;
margin-top: 0px;
width: 30%;
}
#left, #right {
//padding: 10px;
display: inline-block;
height: 800px;
}
add
box-sizing: border-box;
to your divs.
If you don't the padding is added outside the div width (or height).. same as borders
Edited: and
-webkit-box-sizing: border-box; -moz-box-sizing: border-box;
for a bit more browser compatibility
if you are using css3 , you can use box-sizing: border-box;
else, you can have another child div and apply padding to the child div instead of the parent div
#left {
background-color: green;
float: left;
margin-top: 0px;
width: 70%;
}
#right {
background-color: blue;
float: right;
margin-top: 0px;
width: 30%;
}
#left, #right {
padding: 10px;
display: inline-block;
height: 800px;
color:#fff;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
<div id="left"> left </div>
<div id="right"> right </div>

DIV not shrinking when resizing

So I have a site with a simple two DIV panes: a content area left and a fixed 300px menu right, both of them going to a max of 1200px. I want users to be able to resize the window and have the LEFT pane shrink with the right menu staying fixed. But right now I can't find any way to do this, everything looks good at max size, but the left pane doesn't shrink if I resize the window, instead the right menu just wraps to the bottom of the screen. This would be easy with a left menu but the menu is on the right. Here is what I have so far:
#main
{
max-width: 1200px;
margin-right: auto;
margin-left: auto;
margin-top: 0;
display: block;
padding: 0;
}
#left
{
max-width: 890px;
float: left;
padding-right: 10px;
}
#right
{
width: 290px;
top: 0;
float: right;
padding-right: 10px;
padding-left: 10px;
}
you can use CSS calc() to adjust the width of the left container.
OPTION 1 FIDDLE
HTML
<div id="main">
<div id="left"></div>
<div id="right"></div>
</div>
CSS
#main{
width: 100%; //set to 100% since you're capping it at 1200 anyways
max-width: 1200px;
/* margin-right: auto;
margin-left: auto;
margin-top: 0; */ condense these to the following:
margin: 0 auto;
/*display: block;*/ already a block element so not necessary
padding: 0;
overflow: hidden; //add to correct floating elements
}
#left{
background: red; //just for my test
height: 100px; //just for my test
width: calc(100% - 300px); //readjusts based on screen size
float: left;
padding-right: 10px;
-moz-box-sizing: border-box; //if you use padding add these lines to fix issue of padding adding to width
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#right{
background: black; //just for my test
height: 100px; //just for my test
width: 300px;
/*top: 0;*/ //dont need, not doing anything
float: right;
/*padding-right: 10px;
padding-left: 10px;*/ //can condense to following:
padding: 0 10px;
-moz-box-sizing: border-box; //see padding explanation above
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
OR
If you are worried about older browsers you can do this with display: table and display: table-cell like so:
OPTION 2 FIDDLE
CSS
#main{
width: 100%;
max-width: 1200px;
margin: 0 auto;
display: block;
padding: 0;
display: table; //add
table-layout: fixed; //add
}
#left{
display: table-cell; //use instead of float
background: red;
height: 100px;
padding-right: 10px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#right{
display: table-cell; //use instead of float
background: black;
height: 100px;
width: 300px;
padding: 0 10px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Instead of floating the divs, try display: inline-block on the left and right panes, or CSS3 flexbox (depends on how far back you support legacy browsers).
Flexbox example: http://jsfiddle.net/571k3gx2/

how to make div as child of another div?

I want to put three divs in order as following: input, break, ouput. And thier parent div is the container. I am facing problem in applying the box-sizing for these divs, here is my css:
html {
border: groove 8px red;
margin: 20px;
}
.container {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height:75%;
}
.container .input {
width: 49%;
height: 100%;
border: solid 2px red;
float: left;
}
.container .break {
width: 2%;
height: 100%;
background: blue;
float: left;
}
.container .output {
width: 49%;
height: 100%;
border: solid 2px green;
float: right;
}
You have to apply box-sizing to the children as well:
.container > * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
CSS's border-box property doesn't take into account margins. You'll need to set margin of 0 and adjust padding accordingly, but this may be undesired if you're using borders. You can try using percentages for margin so they (widths plus margins) add up to 100%. Also make sure that the child divs are inheriting box-sizing; you may need to define that specifically. I usually set this in CSS:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
Lastly, get rid of that .break div. Use margins instead.
Is your output div dropping below your input and break divs? That's because your border pixels are being added onto your widths.
49% + 2% + 49% + 8px of borders (2 on each side of input and 2 more on each side of output) > 100%
You'll have to try different things to get it to work, but dropping to 48% or even 45% might work. Since your area already floating left & right the extra space will just go in the middle.
this simple three-column layout DEMO
HTML
<div class="header">header</div>
<div class="layout">
<div class="col1">column 1</div>
<div class="col2">column 2</div>
<div class="col3">clolumn 3</div>
</div>
<div class="footer">footer</div>
CSS
.header, .footer { background: #D5BAE4; }
.layout { overflow: hidden; }
.layout DIV { float: left; }
.col1 { background: #C7E3E4; width: 20%; }
.col2 { background: #E0D2C7; width: 60%; }
.col3 { background: #ECD5DE; width: 20%; }
try this (compliments of _s). when you give it a % based width and then a px based border the default is to add them together, this should fix that.
*,
*:before,
*:after { /* apply a natural box layout model to all elements; see http://www.paulirish.com/2012/box-sizing-border-box-ftw/ */
-webkit-box-sizing: border-box; /* Not needed for modern webkit but still used by Blackberry Browser 7.0; see http://caniuse.com/#search=box-sizing */
-moz-box-sizing: border-box; /* Still needed for Firefox 28; see http://caniuse.com/#search=box-sizing */
box-sizing: border-box;
}
LIVE DEMO
HTML
<div class="container">
<div class="input">
</div>
<div class="break">
</div>
<div class="output">
</div>
</div>
CSS
html {
border: groove 8px red;
margin: 20px;
}
.container {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height:75%;
}
.container div{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.container .input {
width: 49%;
height: 100%;
border: solid 2px red;
float: left;
}
.container .break {
width: 2%;
height: 100%;
background: blue;
float: left;
}
.container .output {
width: 49%;
height: 100%;
border: solid 2px green;
float: right;
}

Unwanted space between row of inline-block elements and another row [duplicate]

This question already has answers here:
Why does my image have space underneath?
(3 answers)
Closed 7 years ago.
It isn't a table, I just used "row" for lack of a better word.
My problem is that I've got a set of display:inline-block elements and an element under those, but there's a gap between them. Note that I'm not talking about the space between the inline elements, I'm talking about the space between the row of inline elements and the other element. I've tried the solution mentioned here, setting a line-height and font-size, but that didn't help at all (which is why it isn't in the code below)
Here's my code:
HTML
<div id="letterhead">
<div class="name"></div><div class="logo"></div><div class="name"></div>
<div class="subtext"></div>
</div>
CSS
body{
background:#eee;
width: 100%;
}
#letterhead {
position: absolute;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 12rem;
font: 32px Tahoma;
color: #777;
padding: 2rem;
}
.logo {
display: inline-block;
width: 7rem;
height: 7rem;
background: #000;
}
.name {
display: inline-block;
height: 7rem;
width: calc((100% - 7rem) / 2);
background: #fff;
}
.subtext {
//position: absolute;
margin: 0;
padding: 0;
top: 9rem;
text-align: center;
width: 100%;
height: 1rem;
background: #555;
}
I made a Fiddle here.
Thanks in advance.
But it is because of your font-size and line-height. Set them to 0 on #letterhead and the unwanted white-space will dissapear. You wil have to set your font-size and line-height back on the children of #letterhead if you want to put content in them.
example:
http://jsfiddle.net/skeurentjes/69MkQ/1/
Just add margin:0 -4px 0 0 to your inline-block divs. And everything will be good. To remove space between rows you must set vertical:align:top. Check the DEMO
CSS
.logo {
...
display: inline-block;
margin:0 -4px 0 0;
vertical:align:top
...
}
.name {
...
display: inline-block;
margin:0 -4px 0 0;
vertical:align:top
...
}

How to justify form input fields with css?

I have a simple signup input form (haml for brevity here:)
%form#signup
%fieldset
%input.email{type:'text'}
%br
.name
%input.first-name{type:'text'}
%input.last-name{type:'text'}
and css:
#signup { width: 350px; }
fieldset { width: 100%; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { /* occupy remainder of 'name' line */ }
How to style this so that the .email field is the full width of the fieldset and the .last-name and/or .first-name fields expand to also fill the entire width of the fieldset and with the right edge aligned with the .email field?
Yes it might be easier to use a table here but is there a simple way with css? It need only work for css3 compliant browsers and degrade reasonably for IE8 and 9.
fiddle link: http://jsfiddle.net/3UP9H/1
Original answer appears below the hr; the answer to the question, for clarity, appears to be a combination of box-sizing (and its vendor-previxed variants), in order to include the border-width and padding in the defined width of the elements(s) (rather than their width being defined-width + border-width + padding) and font-size: 0 for the parent element, which removes the errant space between the two input elements (although the space is, technically, still there; it just doesn't have any size to influence the position of the surrounding elements).
So, the CSS is that from the second example below:
fieldset input[type=text] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
width: 350px;
}
fieldset div input[type=text] {
width: 105px;
margin: 0;
}
fieldset div input[type=text] + input[type=text] {
float: right;
width: 245px;
}
div.name {
font-size: 0;
}​
JS Fiddle demo.
Original answer follows:
One way seems to be:
form {
width: 350px;
}
fieldset {
width: 100%;
}
​fieldset input[type=text] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
width: 350px;
}​​
fieldset div input[type=text] {
width: 105px;
margin: 0;
}
fieldset div input[type=text] + input[type=text] {
float: right;
width: 241px;
}​
JS Fiddle demo.
The use of box-sizing (and the vendor-prefixed variants) is to simply include the border of the element, and any assigned padding within the defined width of the element.
I've used self-closing input tags in the linked demo, since input elements, so far as I know, don't have closing tags </input>.
I've amended the above, slightly, to remove the issue of the errant space (between the sibling input elements in the .name element from requiring arbitrary corrections to allow them both on the same line (hence the strange width: 241px in the above CSS):
form {
width: 350px;
}
fieldset {
width: 100%;
}
fieldset input[type=text] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
width: 350px;
}
fieldset div input[type=text] {
width: 105px;
margin: 0;
}
fieldset div input[type=text] + input[type=text] {
float: right;
width: 245px;
}
div.name {
font-size: 0;
}​
JS Fiddle demo.
Edited to remove the fixed-width measurements, and replaced with relative, percentage, based units (as in the original question):
form {
width: 350px;
}
fieldset {
width: 100%;
}
fieldset input[type=text] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
width: 100%;
}
fieldset div input[type=text] {
width: 30%;
margin: 0;
}
fieldset div input[type=text] + input[type=text] {
float: right;
width: 70%;
}
div.name {
font-size: 0;
}​
JS Fiddle demo.
Unfortunately there's no way to set the width of the input elements to 100% by default, while still allowing sibling input elements to have differing widths. Or, there is, but it's substantially more awkward and requires you to explicitly identify both siblings as, although it's possible to select the second, or later, sibling with the + or ~ combinators it's not possible to select the first sibling based on its having subsequent siblings (without JavaScript, or other scripting language, whether client-, or server-, side).
#signup { width: 350px; }
fieldset { width: 100%; border: 1px solid grey; padding:2px;}
.email { width: 99%;margin-bottom:2px; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { width : 67% }
DEMO
Update
#signup { width: 350px; }
fieldset { width: 100%; border: 1px solid grey; padding:2px;}
.email { width: 99%;margin-bottom:2px; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { width : 67%; float:right; }
DEMO
Firefox Screenshot.
Change these two lines to look like this:
.email { width: 99%; float: right; }
.last-name { width: 65%; float: right;}​
Fiddle Link
EDIT The odd thing is that about width in Chrome and IE is that there is an extra 4px width that isn't there in Firefox. The problem is that Chrome and IE add the border to the width of the box, while Firefox compensates the width of the internal textfield to make it fit the border within the bounds specified. See this version of the fiddle for a demonstration.
EDIT2 Check this updated fiddle.