136
votes

I have seen this many a times that the prospect of a negative padding might help the development of CSS of certain page elements become better and easier. Yet, there is no provision for a negative padding in the W3C CSS. What is the reason behind this? Is there any obstruction to the property that prevents it's use as such? Thanks for your answers.

UPDATE

As I see, for example, in case you are using a font that has something, say, a 20px of vertical spacing, and you wish to apply a dashed border to the bottom of the font, say when a hyperlink appears. In such cases you'll find the style to be way too shabby, as the dashed border will appear 20px below the specified word. if you use negative margin, it's not going to work, as margin alters the area outside borders. Negative padding might help in such situations.

7
because it doesn't make sense to have negative paddingPetah
It's the same as you'd see on an HTML generated by Frontpage. It kinda works, but throws a hell of a lot of errors when being validated. Negative padding isn't part of spec but still supported by browsers.Linus Kleen
Many people would like an example. Here is mine and why I woul loooove negative padding. Using the border-image feature, you might want to let the image border slightly overlap the text (for example if you are making a highligted glossy bubble, very popular on the web theese days ;))Himmators
If something "doesn't make sense" to someone, it's no excuse for them to get in someone else's way.Rolf
I am trying to display code in a <span> tag and the way it gets parsed throws extra line breaks at the beginning of the block of code. With negative padding, I could make this extra space go away.Steven Lu

7 Answers

92
votes

I recently answered a different question where I discussed why the box model is the way it is.

There are specific reasons for each part of the box model. Padding is meant to extend the background beyond its contents. If you need to shrink the background of the container, you should make the parent container the correct size and give the child element some negative margins. In this case the content is not being padded, it's overflowing.

6
votes

I would like to describe a very good example of why negative padding would be useful and awesome.

As all of us CSS developers know, vertically aligning a dynamically sizing div within another is a hassle, and for the most part, viewed as being impossible only using CSS. The incorporation of negative padding could change this.

Please review the following HTML:

<div style="height:600px; width:100%;">
    <div class="vertical-align" style="width:100%;height:auto;" >
        This DIV's height will change based the width of the screen.
    </div>
</div>

With the following CSS, we would be able to vertically center the content of the inner div within the outer div:

.vertical-align {
    position: absolute;
    top:50%;
    padding-top:-50%;
    overflow: visible;
}

Allow me to explain...

Absolutely positioning the inner div's top at 50% places the top edge of the inner div at the center of the outer div. Pretty simple. This is because percentage based positioning is relative to the inner dimensions of the parent element.

Percentage based padding, on the other hand, is based on the inner dimensions of the targeted element. So, by applying the property of padding-top: -50%; we have shifted the content of the inner div upward by a distance of 50% of the height of the inner div's content, therefore centering the inner div's content within the outer div and still allowing the height dimension of the inner div to be dynamic!

If you ask me OP, this would be the best use-case, and I think it should be implemented just so I can do this hack. lol. Or, they should just fix the functionality of vertical-align and give us a version of vertical-align that works on all elements.

5
votes

Padding by definition is a positive integer (including 0).

Negative padding would cause the border to collapse into the content (see the box-model page on w3) - this would make the content area smaller than the content, which doesn't make sense.

2
votes

You asked WHY, not how to cheat it:

Usually because of laziness of programmers of the initial implementation, because they HAVE already put way more effort in other features, delivering more odd side-effects like floats, because they were more requested by designers back then and yet they haven't taken the time to allow this so we can use the FOUR properties to push/pull an element against its neighbors (now we only have four to push, and only 2 to pull).

When html was designed, magazines loved text reflown around images back then, now hated because today we have touch trends, and love squary things with lots of space and nothing to read. That's why they put more pressure on floats than on centering, or they could have designed something like margin-top: fill; or margin: average 0; to simply align the content to the bottom, or distribute its extra space around.

In this case I think it hasn't been implemented because of the same reason that makes CSS to lack of a :parent pseudo-selector: To prevent looping evaluations.

Without being an engineer, I can see that CSS right now is made to paint elements once, remember some properties for future elements to be painted, but NEVER going back to already-painted elements.

That's why (I guess) padding is calculated on the width, because that's the value that was available at the time of starting to paint it.

If you had a negative value for padding, it would affect the outer limits, which has ALREADY been defined when the margin has already been set. I know, nothing has been painted yet, but when you read how the painting process goes, created by geniuses with 90's technology, I feel like I am asking dumb questions and just say "thanks" hehe.

One of the requirements of web pages is that they are quickly available, unlike an app that can take its time and eat the computer resources to get everything correct before displaying it, web pages need to use little resources (so they are fit in every device possible) and be scrolled in a breeze.

If you see applications with complex reflowing and positioning, like InDesign, you can't scroll that fast! It takes a big effort both from processors and graphic card to jump to next pages!

So painting and calculating forward and forgetting about an element once drawn, for now it seems to be a MUST.

1
votes

This could help, by the way:

The box-sizing CSS property is used to alter the default CSS box model used to calculate widths and heights of elements.

http://www.w3.org/TR/css3-ui/#box-sizing
https://developer.mozilla.org/En/CSS/Box-sizing

0
votes

Fitting an Iframe inside containers will not match the size of the container. It adds about 20px of padding. Currently there is no easy way to fix this. You need javascript (http://css-tricks.com/snippets/jquery/fit-iframe-to-content/)

Negative margins would be an easy solution.

0
votes

Because the designers of CSS didn't have the foresight to imagine the flexibility this would bring. There are plenty of reasons to expand the content area of a box without affecting its relationship to neighbouring elements. If you think it's not possible, put some long nowrap'd text in a box, set a width on the box, and watch how the overflowed content does nothing to the layout.

Yes, this is still relevant with CSS3 in 2019; case in point: flexbox layouts. Flexbox items' margins do not collapse, so in order to space them evenly and align them with the visual edge of the container, one must subtract the items' margins from their container's padding. If any result is < 0, you must use a negative margin on the container, or sum that negative with the existing margin. I.e. the content of the element effects how one defines the margins for it, which is backwards. Summing doesn't work cleanly when flex elements' content have margins defined in different units or are affected by a different font-size, etc.

The example below should, ideally have aligned and evenly spaced grey boxes but, sadly they aren't.

body {
  font-family: sans-serif;
  margin: 2rem;
}
body > * {
  margin: 2rem 0 0;
}
body > :first-child {
  margin-top: 0;
}
h1,
li,
p {
  padding: 10px;
  background: lightgray;
}
ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  padding: 0;/* just to reset */
  padding: -5px;/* would allow correct alignment */
}
li {
  flex: 1 1 auto;
  margin: 5px;
}
<h1>Cras facilisis orci ligula</h1>

<ul>
  <li>a lacinia purus porttitor eget</li>
  <li>donec ut nunc lorem</li>
  <li>duis in est dictum</li>
  <li>tempor metus non</li>
  <li>dapibus sapien</li>
  <li>phasellus bibendum tincidunt</li>
  <li>quam vitae accumsan</li>
  <li>ut interdum eget nisl in eleifend</li>
  <li>maecenas sodales interdum quam sed accumsan</li>
</ul>

<p>Fusce convallis, arcu vel elementum pulvinar, diam arcu tempus dolor, nec venenatis sapien diam non dui. Nulla mollis velit dapibus magna pellentesque, at tempor sapien blandit. Sed consectetur nec orci ac lobortis.</p>

<p>Integer nibh purus, convallis eget tincidunt id, eleifend id lectus. Vivamus tristique orci finibus, feugiat eros id, semper augue.</p>

I have encountered enough of these little issues over the years where a little negative padding would have gone a long way, but instead I'm forced to add non-semantic markup, use calc(), or CSS preprocessors which only work when the units are the same, etc.