Ensure that there is no overlapping of margins when setting the explicit height of the outer

I am curious about the reason behind this phenomenon.

The inner div has a margin-bottom of 16px.

From what I understand, when the outer div is in contact with the inner div without any padding or border, and the outer div does not have a set height in its CSS style, the inner div will be 16px away from the outer div due to margin overlap. However, if the height CSS style is applied to the outer div, the inner div remains close to the outer div.

Can you provide an explanation for this phenomenon?

.outer {
  background: yellow;
  height: 100px;
}

.inner {
  height: 100px;
  background: green;
  margin-bottom: 16px;
}

.under {
  background: red;
  height: 10px;
}
<div class="outer">
  <div class="inner"></div>
</div>
<div class="under"></div>

Answer №1

Let's tackle this issue head-on:

When you eliminate the height css style on the outer div, you'll notice that the inner div moves down.

This phenomenon is known as Margin Collapsing:

When there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-bottom of a block from the margin-bottom of its last child, the margins collapse. This results in the collapsed margin extending beyond the parent.

Even margins that are zero will follow these rules, causing the margin of a first/last child to extend outside its parent, regardless of the parent's margin being zero or not.

The collapse of the child margin with the parent margin causes the 16px margin to be considered part of the parent.


However, by defining a height, you prevent margin collapsing.

According to the W3 Box Model spec*:

Two margins are adjoining if and only if:

  • Both belong to vertically-adjacent box edges, forming one of the specified pairs, such as the bottom margin of a last in-flow child and bottom margin of its parent if the parent has a 'auto' computed height.

With the absence of margin collapsing, the child's margin simply attempts to increase the height of the outer div, which is not reflected due to the parent having a fixed height of 100px.


However, what if we disrupt the collapse in a different manner? Would the height increase by 16px?

Two margins are adjoining if and only if:

  • no line boxes, no clearance, no padding, and no border separate them

To test this theory, let's introduce a border to violate this rule.

.outer {
  background: yellow;
  border-bottom: 1px solid black;
}

.inner {
  height: 100px;
  background: green;
  margin-bottom: 16px;
}

.under {
  background: red;
  height: 10px;
}
<div class="outer">
  <div class="inner"></div>
</div>
<div class="under"></div>

As anticipated, the margins do not collapse, causing the child's margin to try and increase the parent's height. Without a height property on the parent to offset this, the parent's height expands to 116px.


* Although this references an older spec, the behavior remains consistent. In fact, newer spec documents often refer to this one.

Answer №2

It is not possible to apply a margin to a child element and have it affect the parent element. To add a margin to the parent element, you can use the following CSS code:

.parent {
background-color: yellow;
height: 100px;
margin-bottom: 16px;
}

Answer №3

Inside, positioned within outside, and below placed directly beneath outside without any spacing or padding. This means that no matter the margin applied to inside, there will be no gap between outside and below.

To achieve this, you simply need to add a margin-top to below.

.outside{
    background:yellow;
    height:100px;
}

.inside{
    height:100px;
    background:green;
}

.below{
    background:red;
    height:10px;
    margin-top:16px;
}

Answer №4

Apply the CSS rule to set the height of .outer to 'auto'

.outer{
  background:purple;
  height:auto;
}
.inner{
  height:200px;
  background:blue;
  margin-bottom:20px;
}
.under{
  background:orange;
  height:15px;
}
<div class="outer">
  <div class="inner"></div>
</div>
<div class="under"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The <map> <area> element functions properly only in webkit browsers

Here is some HTML code: <div id="wrap"> <div id="main-content"> <div class="container"> <h1 class="logo">Mysite</h1> <img id="links" src="images/links.png" usemap="map" width="946" heigh ...

Challenge with Express Helmet: CSS fails to load properly on iOS Safari browser

After successfully adding Helmet to my Node/Express/EJS project and configuring my CSP to allow inline scripts, styles, and certain external sources on my Windows laptop in Opera, Chrome & Edge, I encountered a problem when connecting via iOS Safari on mob ...

Adjust the height of the HTML overlay to span the entire visible page

I have a website that utilizes AJAX to load content dynamically. To enhance user experience, I implemented an overlay with a loading indicator during the loading process using jQuery and the jQuery BlockUI plugin. When invoking $(element).block(), everyth ...

Hover Effect for Instagram Feed (Web Application)

Recently, I created an app using the Instagram API to bring Instagram images into a webapp. As part of this project, I have been diving into CSS to implement a rollover effect where a heart icon appears when users hover over an image. This heart will event ...

The canvas game's animation can only be activated one time

I am currently working on designing a straightforward canvas game: Here is the code snippet located on CodePen var canvas; var ctx; var x = 300; var y = 400; var r = 0; var mx = 0; var my = 0; var WIDTH = 600; var HEIGHT = 400; function circle(x,y,r) ...

Solving the mystery of background color in CSS for heading/title div

I am facing an issue with the title div setup where the red background is not applied when only the leftmost div has content. Despite the 'title' div having content, the background remains white. Can anyone suggest why this might be happening? H ...

Is there a way to trigger validation with a disabled property?

My form element is set up like this: <input type="text" id="country" formControlName="Country" /> The form group looks like this: this.myForm = this.formbuilder.group({ 'Country': [{ value: this.user.Country, disabled: this.SomeProperty= ...

Troubleshooting the 'innerHTML' Issue in Your Python Selenium Script

My Python Selenium script for sending emails via Gmail is throwing an error, and I need some assistance to resolve it. The error details are as follows: Traceback (most recent call last): File "C:\Users\Administrator\Desktop\New ...

Leverage the power of JavaScript functions within the app.component.ts file of

I have a JavaScript file named action.js and I am trying to incorporate it into an Angular project. After doing some research, I found out that the js file should be placed in the assets folder and the path must be referenced in the scripts array within an ...

Flex columns with flex items of equal height

I am attempting to create a layout where list items within a column have equal heights. Below is my current code: <ol> <li>List item 1</li> <li>List item 2</li> <li>List item 3</li> </ol> ol { ...

Customize CSS to target the first and last elements in a row using flexbox styling

I am facing a challenge in selecting the last element of the first row and the first element of the last row within a flex container. The setup involves a flex-wrap: wrap; for my flex container where all elements have flex: auto; with different sizes. Thi ...

What is the best way to set inner text using jQuery?

The code snippet below demonstrates a specific issue: <span id="test1">some text</span> <span id="test2">some text</span> Upon loading the content, the following JavaScript is executed: alert($('test1').text(); $(' ...

Using jQuery to insert HTML content into a div element by replacing a specific string

I am faced with a situation where I have <div class="test">hello everyone</div> and the challenge is to replace each instance of "hello" within this div with <h1>helllo</h1> In my attempt, I used $(this).text().replace("hello" ...

Automatically change a text based on its location

Currently leveraging the amazing flexible-nav to showcase the current subtopic within my post. I am also considering the possibility of extracting this current-string and showcasing it at the top of the page in my main navigation bar. This way, the text w ...

Place an element in a higher position than a slideshow

I recently encountered an issue where I was trying to place a png image above my slideshow. Despite trying various solutions, the image always appeared behind or on top without transparency. Based on the erratic display, it seems like the problem might be ...

binding swipe action to click event

I am utilizing images from a database and implementing next and previous buttons for pagination. What I aim to do is connect the click events of these buttons to swipe actions, so that swiping from right to left triggers the next link, while swiping from l ...

Cross-platform mobile browsers typically have scrollbars in their scrollable divs

I have successfully implemented scrollable div's on a page designed for tablets running Android 3.2+, BlackBerry Playbook, and iOS5+ (except iPad 1). However, I would like to add scrollbars to improve the user experience. For iOS5, I can use the suppo ...

Setting the color for the :hover and :active states on a react JSX component: A step-by-step guide

<button onClick={fetchExchangeRates} style={{ backgroundColor: `${selectedColor}` }} className="hover text-white px-3 py-1 flex justify-center items-center gap-2 text- rounded-md" > Convert <FontAwesomeIcon className=&apo ...

I am looking to create a split div with a diagonal line running through

Is there a way I can create this Mockup using html5 and css3, but also add diagonal lines to divide the div? Any suggestions on how to achieve this? ...

Utilize Multidimensional Arrays in HTML

I have a pair of fields called url and id. <input type='url' name='data[web][url]'><input type='number' name='data[web][id]'> <input type='url' name='data[web][url]'><input t ...