Margin, Position and Padding Not Working When Display:Inline Is Set. Also Weird Behaviour from Relative Position

Margin, position and padding not working when display:inline is set. also weird behaviour from relative position

You need to use

display: inline-block;

instead. margin doesn't work with display: inline elements, however with inline-block it does. You can then have an inline element with margins and explicit widths/heights.

To make this work in IE7, add these two lines:

*display: inline;
zoom: 1;

It's horrible, but it works.

Weird padding behaviour for inline element (bottom padding is respected but top padding doesn't)

Use the browser tools to inspect the element and you'll see that there is also a padding-top of 10em, which is not visible in your snippet.

The reason: Although there is a padding for inline elements, it does not affect the distance above and below it - the line (i.e. baseline for the text) is at the same vertical position where it would be (or better: is) without the padding. The padding here just creates an overflowing area which you only see if there is a background defined.

See my snippet, where I added a wrapper with a 12em padding-top and some text before and after the inline div, and also before and after the wrapper div which demonstrates what happens.

* {
box-sizing: border-box;
padding: 0;
margin: 0;
}

.wrap1 {
padding-top: 12em;
background: green;
/* display: block; is the default here */
}

.parent {
display: inline;
background-color: red;
padding: 10rem;
color: white;
}

.y {
background: rgba(255, 255, 0, 0.4);
border-radius: 50%;
padding: 0.6em 0.15em 0.6em 0.1em;
}
<body>
<div>This is in a separate div which preceds the inline div and its wrapper.</div>
<div class="wrap1">
this is on the same the line
<div class="parent">Whatever</div> yes it is
</div>
<div>And this is in a separate div following the inline div and its wrapper.</div>
<p>And here is another line with one (inline) <span class="y">word</span> that has a padding in a way that <em>might</em> be considered useful.</p>
</body>

Parent is inline-block and child has % padding = strange behaviour

You are facing a cyclic calculation due to the use of percentage value. The parent is an inline-block element so its width is defined by its content and that same content is using a percentage value so the content need a reference for that percentage which is the width of the parent. You have a cycle.

In such case, the browser will first ignore the padding to define the parent width and then calculate the padding BUT we don't get to calculate the parent width again because will have an infinite loop.

Check this:

.parent {
display: inline-block;
}

.child {
border: 2px solid red;

}
<div class="parent">
<div class="child">CSSisAwesome</div>
</div>
<br>
<br>
<div class="parent">
<div class="child" style="padding: 20%;">CSSisAwesome</div>
</div>

Are there any limitations of frequently using position tag in CSS instead of using margin and padding tags?

The biggest distinction between position and margin or padding is that when you set the position to absolute, relative or fixed, the element is taken out of the "normal flow" of the document and placed in its own layer. This is what allows you to use the z-index property and stack elements on top of each other. This has dramatic advantages when the elements in question are going to be dynamically sized or animated because doing so won't cause all other elements in the document to have to "re-flow", nor will the entire document have to "re-paint". In fact, when working with dynamic sizing or animations it is strongly recommended that you take elements out of the flow this way or performance can suffer.

Beyond this, understanding how absolute, relative and fixed positioning work is essential.

Absolute Positioning positions the element relative to its nearest ancestor that, itself, has been manually positioned or the body element if no ancestor has been positioned. The element is taken out of the flow and any space the element was taking up in that flow is removed.

Relative Positioning positions the element as an offset to its original location in the normal flow, but leaves the original space that the element took up in the document even though the element is now in its own layer.

Fixed Positioning is similar to absolute, except that the position is not relative to anything. It is fixed at an exact location you specify.

While all of these will pull the element into its own layer, how the layers are stacked (via "stacking contexts") are dependent upon which type of positioning you've used and the structure of the elements being positioned.

These are the reasons to use position. If you are not in need of new layers, using CSS float, flexbox are tools that can offer alternative ways to design a layout.

margin and padding should really not be used for the layout itself. They are used for small tweaks within a layout.

In summary, the default way the a browser lays out the contents of a page is the CSS Box Model, but using CSS position is one way to have certain content use that box model in different layers from the main content. CSS floats offer another, separate layout algorithm and Flexbox offers yet another. In the near future, the CSS Grid specification will be standardized and yet another layout paradigm will be available.

But margin and padding are not layout models. They are just tools to use in whatever layout model you happen to be using.

margin-bottom not working on divs

Change your CSS for the image containers to display: inline-block; instead of display: inline;

This question has been asked before, and has been answered here: https://stackoverflow.com/a/8782644/3781678

inline-block div element doesn't wrap around other inline-block elements

I've achieved a strange hack :
http://jsfiddle.net/CGPBM/

You remove the div.images background, add a border to div.imgContainer and set margin to -1px -1px

.images {    
font-size: 0px;
}

.imgContainer {
max-width: 250px;
max-height: 188px;
position: relative;
display: inline-block;
border: 1px solid white;
margin: -1px -1px;
}

But it has to be tested on several resolutions (JSfiddle is so small ...)

I also applied it to your website, and there is a white space you need to get rid of between
<div class="imgContainer"></div><div class="imgContainer"></div><div class="imgContainer"></div>

Element with CSS display: none; breaking layout - causing misalignment

Scrap Approach and Use Background Images

http://jsfiddle.net/P5CKC/2/

<ul class="menu">
<li><span>Li</span></li>
<li><span>Li</span></li>
<li><span>Li</span></li>
<li class="change"><span>Li</span></li>
<li><span>Li</span></li>
</ul>

CSS

ul.menu {
overlflow: hidden;
}
ul.menu li {
float: left;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
text-align:center;
margin: 0 0 0 -25px;
width: 152px;
line-height: 35px;
height: 35px;
background: url(../bct-white.png) no-repeat;
color: #0091c1;
}
ul.menu li span {
background: url(/green.png) no-repeat 5px 6px;
display: block;
}
ul.menu li.change span {
background-image: url(/red.png);
}

CSS2.0 and browser compatibility

The code application I have provided is Css2.0 and should easily work in IE7 and above.

  1. Removed img tags and implemmented aesthetics (images) as backgrounds
  2. Extra span had to be added because CSS2 allows only 1 background image per element
  3. Li tag holds the arrow background; span tag holds the pepper background
  4. Updated id="change" to class="change". UNLESS you are 100% certain that you will only have one #change element, use a class. This is purely styling and it prevents you from having two menu lists on the same page.
  5. Tweaked your CSS styling a bit as follows:

Removed top padding and increased the height. So your li elements are the same height BUT then added line-height: 35px -> this is the best way to vertically center text. Utlizing top padding works but it is prone to poor browser inconsistency.

Change li elements to floats. Floated elements are the most IE7 friendly method! Even IE6 will not bug out but I don't have that old version to test your webpage in. FYI - ul.menu has to have overflow: hidden to clear the floats.

position: relative; 
cursor: default;

Unless you changed the defaults, you can keep these two properties out. cursor should be default. Position: relative is unnecessary - you aren't using absolute positioning or anything that warrants its need. Now, you can keep these in your declaration. I just like code to be as "slim" as possible.

final words:

Take a look at my CSS. Notice how I used ul.menu in all my declaration. You may want to get in the habit of doign the same; this provides the developer some insight on what the HTML looks like and more importantly - your css will not get overrided if you decide to add <div class=menu> later on. Specfically .menu img would apply to any image tag within the menu div.

Okay - that's it. Let me know if there are any clarfications.

FYI - seeing as this question has a bounty, if you provide me with the background images I can polish my code to suit your needs 100% - perhaps upload them in an edit of your answer.

Margin on child element moves parent element

Found an alternative at Child elements with margins within DIVs You can also add:

.parent { overflow: auto; }

or:

.parent { overflow: hidden; }

This prevents the margins to collapse. Border and padding do the same.
Hence, you can also use the following to prevent a top-margin collapse:

.parent {
padding-top: 1px;
margin-top: -1px;
}

2021 update: if you're willing to drop IE11 support you can also use the new CSS construct display: flow-root. See MDN Web Docs for the whole details on block formatting contexts.


Update by popular request:
The whole point of collapsing margins is handling textual content. For example:

h1, h2, p, ul {
margin-top: 1em;
margin-bottom: 1em;
outline: 1px dashed blue;
}

div { outline: 1px solid red; }
<h1>Title!</h1>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
</div>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
<ul>
<li>list item</li>
</ul>
</div>


Related Topics



Leave a reply



Submit