2

The padding on the div in the following snippet only pads it vertically:

.col-sm-2 {
  background: pink;
  padding: 100px;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div class="container">
  <div class="row">
    <div class="col-sm-2"></div>
  </div>   
</div>

This is because Bootstrap's has .row > * applying padding-left and padding-right.

However, overriding the padding with !important only takes effect starting from a certain point (which seems to be padding: 45px in this case), so that setting it to less than that doesn't work horizontally:

.col-sm-2-a {
  background: pink;
  padding: 30px !important;
}
.col-sm-2-b {
  background: pink;
  padding: 40px !important;
}
.col-sm-2-c {
  background: pink;
  padding: 50px !important;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div class="container">
  <div class="row">
    <div class="col-sm-2 col-sm-2-a"></div>
  </div> 
  <br />
  <div class="row">
    <div class="col-sm-2 col-sm-2-b"></div>
  </div> 
  <br /> 
  <div class="row">
    <div class="col-sm-2 col-sm-2-c"></div>
  </div> 
</div>

And here it is animated:

.col-sm-2 {
  background: pink;
  animation: myanim 10s infinite;
}
@keyframes myanim {
   50% {
      padding: 100px;
   }
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div class="container">
  <div class="row">
    <div class="col-sm-2"></div>
  </div>   
</div>

Question: What makes the padding not work both vertically and horizontally until a certain point, and what changes from that point that allows the padding to work horizontally?

OfirD
  • 9,442
  • 5
  • 47
  • 90

3 Answers3

2

In the snippet, the width of the row is 540px, thus the width of a col-sm-2 is 2 / 12 * 540 = 90px. The corresponding rule :

@media (min-width: 576px)
.col-sm-2 {
    flex: 0 0 auto;
    width: 16.66666667%;
}

But we also have this rule declaration setting the box-sizing property of all elements to border-box :

*, ::after, ::before {
    box-sizing: border-box;
}

With box-sizing: border-box; :

The dimensions of the elements are calculated as: width = border + padding + width of the content, and height = border + padding + height of the content.

In this example we have no border, only padding and width/height. The width of ~16.7% will be applied to the border-box of the element.

With a padding set to 30px, the width of the element is 30 (padding-left) + 30 (padding-right) + the missing pixels to reach 16.7% (30).

When set to 45px, the width is 45 + 45 + 0.

According to the documentation :

The content box can't be negative and is floored to 0, making it impossible to use border-box to make the element disappear.

That is why with a padding of 50px, the total width is 100px (50 + 50 + 0) and not 90px (50 + 50 - 10).

Consequently, the width of the element can go beyond 90px only when the padding is set to more than 45px (more precisely if padding-left + padding-right > 90px).

Tom
  • 4,972
  • 3
  • 10
  • 28
  • Thanks for this detailed answer. One thing: the last paragraph confused me. Is citing "The content box can't be negative and is floored to 0 etc" of relevance here? after all, the content box is not being set to negative and is not floored to 0; it is 90 (and it's only the "gap" pixels being 0). Is that correct? – OfirD Nov 24 '21 at 11:05
  • @OfirD I thought it was relevant to explain why with a padding of `50px`, the total width is `100px` (50 + 50 + 0) and not `90px` (50 + 50 - 10) to respect the width property set to `16.7%`. But you're right, I may have placed it wrongly. – Tom Nov 24 '21 at 12:57
  • 1
    Oh I see what you mean now, being explicit and mentioning `(50 + 50 - 10)` is helpful, I suggest you to insert that into your answer as well :) – OfirD Nov 24 '21 at 13:47
0

In your first code snippet you've mentioned that 100px pads only vertically. Then you've used !important in next snippet. So I think you are using important because 100px padding didn't have any effect in first code snippet. And you didn't put link to bootstrap css intentionally in the body instead of putting it in head section before your own style tag. If that is not the case then ignore following suggestion.
Order where you put CSS rules does matter. If you put the links in head section, before your own styles, then 100px padding will work.

<!DOCTYPE html>
<html>

<head>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

  <style>
    .col-sm-2 {
      background: pink;
      padding: 100px;
    }
  </style>

</head>

<body>
  <div class="container">
    <div class="row">
      <div class="col-sm-2"></div>
    </div>
  </div>
</body>

</html>

As for why 45px is the turning point. As @tom suggested the element has 90px width. And as you keep on adding padding it eats into width till width becomes 0. After that the element starts growing to accommodate padding.

<!DOCTYPE html>
<html>

<head>
  <style>
    .one {
      background: pink;
      height: 100px;
      padding: 0px !important;
    }
    
    .two {
      background: wheat;
      height: 100px;
      padding: 46px !important;
    }
  </style>

</head>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<body>
  <div class="container">
    <div class="row">
      <div class="col-sm-2 one"></div>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <div class="col-sm-2 two"></div>
    </div>
  </div>

</body>

</html>

First dive has 0 padding thus it has full width 90px: enter image description here


Second div has 46 padding thus it has no width left: enter image description here


@MRadev has made a good suggestion. You should try to stick to the library/framework/toolkit you are using.
Following is the same first code snippet in OP trying to use as many bootstrap classes as possible.

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<body>
  <!-- using available bootsrap classes-->
  <div class="container">
    <div class="row">
      <div class="col-sm-2 bg-danger p-5"></div>
    </div>
  </div>
  <!-- extending with specific classes -->
  <style>
    .p-100 {
      padding: 100px !important;
    }
    
    .bg-pink {
      background-color: pink !important;
    }
  </style>
  <div class="container">
    <div class="row">
      <div class="col-sm-2 bg-pink p-100"></div>
    </div>
  </div>

This discussion will help you add more spacing options: https://stackoverflow.com/a/46125059/15273968
https://getbootstrap.com/docs/4.6/utilities/spacing/
https://getbootstrap.com/docs/4.6/utilities/colors/
the Hutt
  • 16,980
  • 2
  • 14
  • 44
0

In relation to the answer of @onkar ruikar please have in mind that when you are using an external library such as Bootstrap in your case, the overwriting of styles might not work even with !important due to the priority of rules.

In many cases, such libraries generate really specific rulesets for their elements. Your options for overwriting them are either be MORE specific than them (which doesn't always work) or use !important as you have tried.

The reason that @onkar ruikar's answer works - putting the your styles in the head is because when browsers are reading multiple !important rules for any given style, they cannot know what to prioritize and they "give up" after the fist one and apply it.

MRadev
  • 411
  • 9
  • 19