Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unwanted margin appearing out of nowhere, despite being set to 0

Tags:

css

the input field

the chrome dev panel

If I hover over the element in the dev panel, it shows an orange highlight over the margin making up the difference between the field above and the field below. I can't capture that in a screenshot because of the way the VM I am developing on is set up, but please trust me that it is there. However, on the 2nd image, you can see margin is set at 0 and the rule is being used, and to the right it shows the right margin as being - (meaning none). How can I get rid of this margin? It is driving me crazy, I've been playing around with the rules on the input and the element containing it for hours, with no luck.

I can't use the style from the 2nd input to help, because that one actually extends beyond what you can see, having the last 30% of its width covered up, which is what I am trying to get rid of on all my inputs.

The CSS of the input:

border: 2px solid #c7d9e7;
border-bottom: none;
border-radius: 2px;
color: $text-black;
display: flex;
flex-grow: 1;
font-family: 'open_sansregular', sans-serif;
font-size: 1em;
font-weight: normal;
margin: 0;
order: 2;
padding: 2px 5px;
width: auto;

The CSS of the parent element (a span, whose only child element is the input field):

display: block;
overflow: hidden;
position: relative;
text-align: center;

EDIT: My goal is to have the input fill the parent width, which extends as far as the visible edge of the bottom field.

like image 221
Clinton J Avatar asked Dec 09 '25 17:12

Clinton J


1 Answers

tl;dr Use

input {
   width: 100%;
   box-sizing:border-box;
}

Below, should you be interested, is a full answer of what's happening and why the above solution works.

There's various rules being applied from multiple specifications which we need to bring together.

First of all, let's establish what we're discussing. We have a span, inside of which is a input control.

input {
  border: 2px solid #c7d9e7;
  border-bottom: none;
  border-radius: 2px;
  color: black;
  display: flex;
  flex-grow: 1;
  font-family: 'open_sansregular', sans-serif;
  font-size: 1em;
  font-weight: normal;
  margin: 0;
  order: 2;
  padding: 2px 5px;
  width: auto;
}
span {
  display: block;
  overflow: hidden;
  position: relative;
  text-align: center;
}
<span>
  <input type="text">
</span>

Orange box shown in Chrome to the right of the input control

And I believe that it's the orange box to the right of the input control that you are asking about. You want to know (a) why the orange box has a large width when the box model values shown say it should be 0. And (b) how to reduce this width and use the space available for the input control instead.

The first step is to understand that there are several different value stages for each property. From CSS 2.2, Section 6.1 Specified, computed, and actual values we have the Specified, value, the Computed value, the Used value and the Actual value; and from the CSSOM specification we also have the Resolved Value

What you write in the stylesheet is the Specified value. input { margin-right:0; } means that the specified value of margin-right property of the input element is zero.

The value you see in the box model depiction is the Computed value. In this case, that's also zero.

The orange box is showing you the width of the Used value - or the Resolved value which for margin properties on visible elements is the same as the Used value.

So part (a) of the question becomes: why is the Used value different from the Computed value?

You have made the input element display:flex. This makes the element block-level.

'flex'
   This value causes an element to generate a block-level flex container box.

Also in the HTML5 spec, Rendering section Section 10.5.4. The input element as a text entry widget. it says:

If an input element whose type attribute is in one of the above states does not have a size attribute, then the user agent is expected to act as if it had a user-agent-level style sheet rule setting the width property on the element to the value obtained from applying the converting a character width to pixels algorithm to the number 20.

So an intrinsic width of about 20 characters is assigned to the input element.

In the CSS 2.2 spec, we can now see how the widths of and around the input element are calculated. First section 10.3.4 Block-level, replaced elements in normal flow applies:

The used value of 'width' is determined as for inline replaced elements ...

The used value rule for inline replaced elements is from section 10.3.2 Inline, replaced elements

If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.

and we've already established that the intrinsic width is 20 characters.

Section 10.3.4 Block-level, replaced elements in normal flow goes on to say:

.. Then the rules for non-replaced block-level elements are applied to determine the margins.

Which is section 10.3.3 Block-level, non-replaced elements in normal flow and importantly says that for the Used values, this equality MUST hold:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

You've made the span element display:block, so the span element is the containing block element.

None of the Used values within that equality are "auto", so the values are said to be "over-constrained". That means that to make the equality hold, at least one of Used values must be different from the Computed value. The section goes on to say that:

... the specified value of 'margin-right' is ignored and the [Used] value is calculated so as to make the equality true ...

So that calculated margin-right value is what you see depicted as the Orange box.

Now we can see how to fix it. All we have to do is to stop the equality from adjusting the Used margin-right value by setting the content-box width of the input box to the full width of the span, less the padding and borders. Then the Used values of the margins will be 0. For that we use

input {
   width: 100%;
   box-sizing:border-box;
}

or

input {
   width: calc(100% - 14px);
}

input {
  border: 2px solid #c7d9e7;
  border-bottom: none;
  border-radius: 2px;
  color: black;
  display: flex;
  flex-grow: 1;
  font-family: 'open_sansregular', sans-serif;
  font-size: 1em;
  font-weight: normal;
  margin: 0;
  order: 2;
  padding: 2px 5px;
  width: 100%;
  box-sizing:border-box;
}
span {
  display: block;
  overflow: hidden;
  position: relative;
  text-align: center;
}
<span>
  <input type="text">
</span>
like image 54
Alohci Avatar answered Dec 15 '25 17:12

Alohci



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!