TL;DR
The problem appears because of the column gutter, which by default is 30px. This means the minimum width of a column will always be 30px, no matter size it would have. Therefore, when you have a column with a width less than 30px, it is actually still going to have 30px as total width, and the columns will eat from each other because of that padding.
In detail
The working snippet
Firstly, I want to show you the working snippet I have managed to get. I have removed the inline styling from the HTML markup and added some CSS classes for better readability and easier understanding.
.pa-0 {
padding: 0 !important;
}
.ma-0 {
margin: 0 !important;
}
.my-button {
display: block;
height: 20vmin;
border: none;
outline: none;
background: transparent;
}
.bg-green {
background-color: green;
}
.bg-red {
background-color: red;
}
.bg-black {
background-color: black;
}
.bg-blue {
background-color: blue;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="container">
<div class="row">
<div class="col-xs-3 pa-0 bg-blue">
<div class="row ma-0">
<div class="col-xs-1 pa-0 bg-green">
<button class="button my-button" type="button">
</button>
</div>
<div class="col-xs-10 pa-0 bg-red">
<button class="button my-button" type="button">
</button>
</div>
<div class="col-xs-1 pa-0 bg-black">
<button class="button my-button" type="button">
</button>
</div>
</div>
</div>
</div>
</div>
The problem
The problem described appears because of the way columns and rows are styled in Bootstrap. As you may already know, columns are having a gutter (padding) of 15px on each side, and rows have a margin of -15px, whose purpose is to remove the padding from the parent container (assuming correct syntax is applied, i.e. parent is a container or column). This means that the spacing created by the parent div is removed with the negative margin from the row.
This is a neat way of creating responsive design, but it also has an issue, which is the one you describe. Because all elements in Bootstrap have box-sizing: border-box
, it means that the width of an elements is including the padding.
For example, if you have an column with the width of 100px, its size will be decreased by the gutter, which is by default 30px. Therefore, the actual width of the column will be 70px.
Having that said, let's think what is happening when the width of this column is less than 30px.
Our column is now 20px in width. As we need to decrease this size by the 30px gutter, we would normally get a negative width, which is impossible. Thus, the actual width of the column will be 0, and the padding will still be applied as 30px.
A solution
Simply create some utility classes which removes the padding and margins from the columns and rows. This way, the column will have the size they should, and the buttons will correctly be fit in their parents without being eaten by the padding from other elements.
I have used the same naming for the padding and margin utility classes as in Bootstrap 4. In pa-0
, p comes from padding, a from all and 0 from the value set to this attribute.
Notes for your initial snippet
I am not sure the markup you have provided is in the way you normally do it, but it is worth to note:
- It is generally a bad practice to have inline-styling set in your HTML markup1; mainly because of the Separation of Concerns principle and the reuse of styling you write. In your case, except for the background, you have used the same styling for buttons in three places - you can just create a new CSS class and use it in all three places.
- In the Bootstrap grid system2, the column needs to always be a direct descendant of a row, and the row needs to be either descendant of a container or column, as you can see in the working example. By not having correct Bootstrap markup, unexpected styling behaviour might occur.
Useful links
- SO post: What's so bad about inline styling?
- Separation of Concerns in Web Development at Wikipedia
- The Bootstrap 3 grid system
box-sizing
at CSS-Tricks
- The Definitive Guide to Using Negative Margins at Smashing Magazine
- Bootstrap 4 Spacing utility classes