-1

.search {
  margin: 10px;
}

.search::before {
  content: "";
  position: absolute;
  top: 50%;
  bottom: auto;
  width: 20px;
  height: 20px;
  transform: translateY(-50%);
  background: url('magnifying-glass.svg');
}

input[type="search"] {
  height: 30px;
  padding-left: 30px;
  border: none;
  border-radius: 0.25rem;
  outline: none;
}

.container {
  position: relative;
  background-color: cadetblue;
}
<div class="container">
  <div class="search">
    <form>
      <input type="search" placeholder="Search...">
    </form>
  </div>
</div>

I am fairly new to css. According to my assumptions, my input[type="search"] should have 10px margin to the borders of the div.container because I have set the margin on div.search, however, as you can see in code snippet above, my input element and div.container is sharing borders.

Can you eloborate on what I am missing to make it work? I am especially interested to see the flaw in my reasoning.

VXp
  • 11,598
  • 6
  • 31
  • 46
yasar
  • 13,158
  • 28
  • 95
  • 160

1 Answers1

3

TL;DR

.search {
  display: inline-block;
}

Explanation

The margins between .container and .search collapse, based on the margin collapsing rules in effect about parent and child elements.

Excerpt from the releveant MDN page:

Parent and first/last child

If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of its first child block; or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block from the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.

Based on that you can prevent collapsing margins by creating a new block formatting context. This can be done by e.g. setting display: inline-block on the the child element.

In action

.search {
    display: inline-block;
    margin: 10px 10px 10px 10px;
}

.search::before {
    content: "";
    position: absolute;
    top: 50%;
    bottom:auto;
    width: 20px;
    height: 20px;
    transform: translateY(-50%);
    background: url('magnifying-glass.svg');
}

input[type="search"] {
    height: 30px;
    padding-left: 30px;
    border: none;
    border-radius: 0.25rem;
    outline: none;
}

.container {
    position: relative;
    background-color: cadetblue;
}
<html>
    <head>
        <title>Test HTML and CSS</title>
        <script src="main.js"></script>
        <link rel="stylesheet" href="main.css">
    </head>
    <body>
        <div class="container">
            <div class="search">
                <form>
                    <input type="search" placeholder="Search..."/>
                </form>
            </div>
        </div>
    </body>
</html>
marionebl
  • 3,342
  • 20
  • 34