149

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.

ikartik90
  • 2,695
  • 6
  • 26
  • 38
  • 30
    because it doesn't make sense to have negative padding – Petah Feb 11 '11 at 21:01
  • Can you propose an example where negative padding would benefit the output? I can see negative margins, but I can't think of a good example where I'd need to extend the margin. – Brad Christie Feb 11 '11 at 21:02
  • 1
    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 Feb 11 '11 at 21:02
  • 9
    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 Sep 03 '11 at 07:55
  • 96
    If something "doesn't make sense" to someone, it's no excuse for them to get in someone else's way. – Rolf Nov 03 '11 at 12:10
  • 1
    I am trying to display code in a `` 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 Jul 23 '12 at 06:23
  • What would be the purpose of negative padding? Padding is used to shrink the content in its box leaving space between the border and the content. Unless the purpose is to pull the content out of its box beyond its boundaries which I don't see it being useful. May be someone may have a different opinion. – Izhar Feb 28 '11 at 01:40
  • As written in the original post, one possible purpose is to cancel the effect that a border has on element size, in a way turning the border into an outline. The outline property cannot be applied to a unique side of a container - border can. There are other cases, and even if there aren't CSS is not perfect and I'm sure negative padding will prove to be handy in some situations. Beginners will not think about using it, people who write unmaintainable code already have enough tools at their disposal, and will do so anyway, and, the rest, the proper developers, might need it occasionally. – Rolf Nov 03 '11 at 10:50
  • 1
    @Petah It doesn't make sense to have a negative margin either and yet that is supported. And just as there are situations you can solve with a negative margin, there are also situations that you could solve with a negative padding, like making sure the border width is subtracted from the element's width/height and won't extend these values. – Mecki Apr 20 '20 at 00:34
  • @Mecki isn't that what `box-sizing` is for? – Petah Apr 21 '20 at 02:12

7 Answers7

98

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.

Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • 2
    Thanks bud. That gives me a satisfactory reason. Cheers. :) – ikartik90 Feb 12 '11 at 06:29
  • 11
    What if you want to shrink the border closer to the text, for example when you are using a border image. – Himmators Sep 03 '11 at 07:57
  • 5
    sometimes it's not practical to edit the CSS of all children of a container. You might have generic CSS that applies to these elements across the document, and you don't want to change it for the contents of a particular container, for example. – Rolf Nov 03 '11 at 10:57
  • However, you may not have direct control over the child element, for example if it is an embedded widget. – Mike C Feb 15 '12 at 00:14
  • 18
    Eh, it's a reason, but I wouldn't call it a satisfactory one. This is a case where the spec goes beyond telling me how to define my page and starts telling me how I *should* define my page. If I want my content to overlap my background edges, borders and/or margins, that should be my prerogative, the spec definers' imaginations of why I might want to do so notwithstanding. Sorry, just a little irritated that I have to add syntactical cruft or worse, single pixel wide single color images to get a specifically sized separator that's smaller than text height and centered vertically. – Jason Sep 03 '13 at 20:59
  • @Jason, the comments of this [SO] answer are probably not the best place to be voicing your concerns. If you'd like to make a constructive difference in how CSS is defined and (eventually) rendered, I recommend participating in the [w3c mailing list for CSS](http://lists.w3.org/Archives/Public/www-style/). – zzzzBov Sep 03 '13 at 21:10
  • 2
    @zzzzBov, I felt it was relevant due to the example I gave at the end for why I would want to do such a thing, which is a common question in the comments on this page. Admittedly, my horse was a little high leading up to that point. – Jason Sep 03 '13 at 21:26
  • There are MANY things that don't make sense in HTML, if you compare it with real-world objects. The usual reasons for someone using the double standard for stopping at such a small exception while having created many others, is because of laziness. Simply because it was not requested back then One good reason for negative padding is because in your own example, you have to setup many other different values, instead of just one. Without negative padding you are LOSING one out of 4 ways to pull-push content against another container (padding-margin-margin-padding) and are forced to add elements. – sergio Jul 19 '15 at 19:10
  • Thank you for opening my mind after hours of struggle to find a solution. – Vinicius Tavares Feb 04 '16 at 04:21
  • This is a terrible answer, it applies the logic of physical items to abstract 2D shapes which have no such constraints. – Walf Feb 08 '19 at 02:58
8

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.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 46
    The border collapsing into the content is exactly the wanted effect. Do you know of any other way of obtaining this effect? – Rolf Nov 03 '11 at 10:59
  • 4
    Agreed with Rolf. You, Oded, obviously are not into complex experimental design, I can see. Using negative padding, and border, while not being able to use explicit pixel values it is practically impossible to get similar results. As far as I know you would need multiple nested elements in order to achieve the same thing, however, things get a bit more complicated then, in some cases. – Yeti Jul 29 '13 at 19:32
6

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.

WebWanderer
  • 10,380
  • 3
  • 32
  • 51
  • 1
    Yes, but for that purpose I'd rather have new attributes for html elements, rather than hijacking other attribute's behavior. Your example calls for a new inner-top attribute; like relatively-positioned element's top attribute, but relative to self, not to parent. Another good use of negative padding would be making an element proportionally to its width filling with 100% padding, but allowing the element to grow vertically if more content overflows it, which is impossible if the content is in an extra abs-pos sibling. Negative padding would take the padding-collapsed element back to its size. – sergio Jul 19 '15 at 19:29
  • in 2018 centering is as easy as using display flex with justify content and align-items... 3 lines of code to have perfect centered div. – kaiser Nov 04 '18 at 17:29
3

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.

sergio
  • 997
  • 1
  • 11
  • 15
2

Update: flexbox now has the gap property to overcome the specific issue outlined below, but it doesn't change the fact that negative padding could solve many style issues that can only be worked around by tricks such as a non-semantic wrapping element with negative margins between a parent and its semantic children.


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 technically 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. It seems to be a rigid interpretation based on physical constraints that simply do not apply to digital objects. There's no reason why margin can't continue to mean the distance of the 'outer' edge to the adjacent elements, with padding being a relative position of an element's content from that outer edge.

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.

Walf
  • 8,535
  • 2
  • 44
  • 59
2

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

Rolf
  • 5,550
  • 5
  • 41
  • 61
0

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.

john k
  • 6,268
  • 4
  • 55
  • 59