null
null

Reputation: 1433

How to prevent adjoining elements from moving when increasing border width?

I have a simply layout that consists of boxes.

 .action_box {
   width: 300px;
   height: 200px;
   border: 1px solid black;
   float: left;
   margin-left: 10px;
   margin-top: 10px;
 }
 .action_box p {
   border: 1px solid black;
   margin-top: 0px;
   text-align: center;
 }
 .action_box:hover {
   border: 2px solid black;
   cursor: pointer;
 }
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>

When hovering about one box I want it to get a broader border. Actually it works, but all other boxes are moving away and destroying the website. How can I prevent such behavior? Adding a padding does not achieve this goal.

I read this post and the only possible solution would be to use position: absolute;. I'd need to assign individual parameters to each box. Isn't there an easier way, but I would like to use only one class.

Upvotes: 17

Views: 12967

Answers (4)

Kodd
Kodd

Reputation: 163

Another approach would be to add a transparent border to the element before hand, so it already occupies the space and will not move when the border-color is changed.

Upvotes: 3

Joseph Marikle
Joseph Marikle

Reputation: 78520

Pretty easy to do actually. If you don't want to go the absolute position route, you can do it two ways: substitute a box-shadow the increased border if your don't mind the compatibility compromise or use box-sizing:border-box. The only problem with box-sizing:border-box is that it shifts your content inward (the style rule calculates the total width + padding + border-width in the width attribute. If you set a 5px border to a 100px box, the width is normally 110px to include both left and right borders. With the box-sizing attribute it calculates the border width into the width making it 90px wide instead to allow for the 10px of border width).

j08691 already has the box-sizing solution in his answer, so here is the box-shadow method (notice that I only added 1px of box shadow. This is because the border is still present providing half of the desired width):

 .action_box {
   width: 300px;
   height: 200px;
   border: 1px solid black;
   float: left;
   margin-left: 10px;
   margin-top: 10px;
 }
 .action_box p {
   border: 1px solid black;
   margin-top: 0px;
   text-align: center;
 }
 .action_box:hover {
   box-shadow: 0 0 0 1px black;
   cursor: pointer;
 }
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>

If, however, you want neither of these approaches, there is still the position:absolute solution. For this method, you don't need another class or anything like that. You can use a pseudo-element instead. This is probably overkill for what you need, but it is still an option.

 .action_box {
   width: 300px;
   height: 200px;
   border: 1px solid black;
   float: left;
   margin-left: 10px;
   margin-top: 10px;
   position: relative; /* give it some context */
 }
 .action_box p {
   border: 1px solid black;
   margin-top: 0px;
   text-align: center;
 }
 .action_box:hover:after {
   content: '';
   position: absolute;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   border: 2px solid black;
   cursor: pointer;
 }
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>

Upvotes: 16

lmgonzalves
lmgonzalves

Reputation: 6588

A possible solution could be using box-shadow instead border:

.action_box:hover {
    box-shadow: inset 0 0 0 1px black;
}

DEMO

Note: With this solution the inner content don't move neither :)

Upvotes: 7

j08691
j08691

Reputation: 207861

Add box-sizing:border-box; to your .action_box class:

.action_box {
   width: 300px;
   height: 200px;
   border: 1px solid black;
   float: left;
   margin-left: 10px;
   margin-top: 10px;
  box-sizing:border-box;
 }
 .action_box p {
   border: 1px solid black;
   margin-top: 0px;
   text-align: center;
 }
 .action_box:hover {
   border: 2px solid black;
   cursor: pointer;
 }
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>
<div class="action_box">asdasds</div>

Upvotes: 6

Related Questions