CSS borders interfering with absolute positioning

2020-08-09 12:00发布

问题:

[edit: clarified that box-sizing: border-box doesn't seem applicable, since I'm using absolute positioning]

The following code illustrates my problem. I'm using absolute positioning, because I found this even trickier with flow-based layout, but I'm open to suggestions. What I want is borders around arbitrary elements, without the borders affecting the positioning of the nodes. (The borders may clip or be overwritten by the content, but that doesn't matter.)

In particular, the borders of a parent must be able to overlap with the borders of its children, which is not the default behaviour. The CSS box-sizing attribute can be set to border-box to achieve the effect I want, but only (I believe) with inline elements. It has no effect on elements with absolute positioning (as I understand things).

So, my approach has been to use a negative margin to offset the positions of the children by the width of the border. This does indeed seem to cancel out the effect of the border's presence, but unfortunately not in a way which is consistent across scaling factors. At large scales, things look ok. At the default browser zoom in Chrome, the element positioning goes a bit off (they appear too high); if I go smaller, then the element position goes off in the other direction.

But if I remove the borders entirely, the layout seems to scale ok.

So my question is: is there a reliable (scalable) way to have borders on HTML elements with no impact on the positioning of the elements?

[In the example, I've used different colours for some of the borders. I would like to see only black, but at some zooms I can see red and green borders, showing that the element's position is being affected by the presence of the border.]

thanks Roly .bordered { position: absolute; height: 18px; border: 2px solid; margin: -2px; }

<span class="bordered" style="width: 55px; left: 30px;">
  <span class="bordered" style="width: 8px; left: 0;">
    (
  </span>
  <span class="bordered" style="border-color: green; width: 47px; left: 8px;">
    <span class="bordered" style="border-color: red; width: 39px; left: 0;">
      <span class="bordered" style="width: 8px; left: 0;">
        5
      </span>
      <span class="bordered" style="width: 31px; left: 8px;">
        <span class="bordered" style="width: 23px; left: 8px;">
          Nil
        </span>
      </span>
    </span>
    <span class="bordered" style="width: 8px; left: 39px;">
      )
    </span>
   </span>
 </span>

回答1:

Try out CSS2 outline property:

.bordered {
    outline:2px solid blue;
}

Outline does not affect element position.

You can also use CSS3 outline-offset as seen here: http://www.css3.info/preview/outline/



回答2:

I also discovered that using a border of zero width (so that it doesn't affect layout), and then adding a box-shadow to emulate a visible border, seems to work well.



回答3:

Six years later...

The other answers didn't work for my situation since the box I was styling already had a box-shadow. I needed a border on just one side like border-left and a border-radius, but without the border affecting the position or width of the element. The solution I came up with was to apply the border on an inner element of the absolutely positioned element.

.outer {
  position: absolute;
  width: 200px;
  height: 100px;
  border-radius: 5px;
  background-color: #c8c8c8;
}

.inner {
    height: 100%;
    min-height: 100%;
    min-width: 100%;
    width: 100%;
    border-left: solid 5px #097fee;
    border-radius: 5px;
}
<div class="outer">
  <div class="inner">
    Some content
  </div>
</div>