210

On click I am adding, 1px border to div, so Div size increases by 2px X 2px. I dont want to get div size increased. Is there any simple way to do so?

Messy Detailed Explanation
Actually I am adding DIVs with float:left (same size, like icons) to a container-div, so all stacks up one after another, and when (container-div width is 300px) no space left width-wise so child DIVs comes in next row, so its like catalog, but because of border only selected DIV size get increased, DIV under selected DIV goes to right and creates empty space below selected DIV.

EDIT:
Decreasing Height/Width on selection, but how to increase it back. Using some 3rd party framework, so don't have event when DIV loses selection..

Cœur
  • 37,241
  • 25
  • 195
  • 267
Nachiket
  • 6,021
  • 6
  • 41
  • 47

18 Answers18

148

This is also helpful in this scenario. It allows you to set borders without changing div width

textarea { 
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;         /* Opera/IE 8+ */
}

Taken from http://css-tricks.com/box-sizing/

PPG tv
  • 98
  • 2
  • 7
ejfrancis
  • 2,925
  • 4
  • 26
  • 42
  • 6
    box-sizing: border-box should really be set on everything as a modern best practice. See https://www.paulirish.com/2012/box-sizing-border-box-ftw/ – jbyrd Apr 04 '17 at 12:42
  • 19
    This doesn't seem to work in some cases; not exactly sure why. See: https://codepen.io/anon/pen/QZaBQG – W Biggs Oct 16 '18 at 17:14
  • 1
    @WilsonBiggs Yes! It is not reliable at all! – 71GA Oct 12 '20 at 16:28
  • yeah browser likes to make the elements bigger when adding border some times even with box sizing set.... – ICW Nov 10 '22 at 23:05
  • 5
    If a width isn't set on the element it ignores box-sizing: border-box. – SethWhite Dec 05 '22 at 20:13
110

If you don't have a border-radius change border to outline:

outline: 1px solid black;
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
panwp
  • 1,109
  • 1
  • 7
  • 2
88

Having used many of these solutions, I find using the trick of setting border-color: transparent to be the most flexible and widely-supported:

.some-element {
    border: solid 1px transparent;
}

.some-element-selected {
    border: solid 1px black;
}

Why it's better:

  • No need to to hard-code the element's width
  • Great cross-browser support (only IE6 missed)
  • Unlike with outline, you can still specify, e.g., top and bottom borders separately
  • Unlike setting border color to be that of the background, you don't need to update this if you change the background, and it's compatible with non-solid colored backgrounds.
Edward Newell
  • 17,203
  • 7
  • 34
  • 36
71

set a border on it before you click to be the same color as the background.

Then when you click just change the background color and the width will not change.

corymathews
  • 12,289
  • 14
  • 57
  • 77
70

The border css property will increase all elements "outer" size, excepts tds in tables. You can get a visual idea of how this works in Firebug (discontinued), under the html->layout tab.

Just as an example, a div with a width and height of 10px and a border of 1px, will have an outer width and height of 12px.

For your case, to make it appear like the border is on the "inside" of the div, in your selected CSS class, you can reduce the width and height of the element by double your border size, or you can do the same for the elements padding.

Eg:

div.navitem
{
    width: 15px;
    height: 15px;
    /* padding: 5px; */
}

div.navitem .selected
{
    border: 1px solid;
    width: 13px;
    height: 13px;
    /* padding: 4px */
}
ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Sean Amos
  • 2,260
  • 19
  • 13
  • thnx, i had .dragdrop-selected class but it was used by all dragable objects and I had like 3 different size (3 different type) of Dragable object, so I kept padding same in all 3 AND set padding in .dragdrop-selected.. & it worked. :) – Nachiket Jul 15 '10 at 16:40
  • 3
    This is not a good solution for responsive designs. Using `outline` or a border with same color as background (and changing its color to something else when is selected) is more flexible. – AliBZ Oct 01 '15 at 22:23
  • 2
    But suppose you need to avoid hard-coding the width, to let the element flow or respond to the view-port width: see my answer using `border-color: transparent` – Edward Newell Apr 30 '16 at 04:11
  • 1
    No need for these calculations, just set box-sizing to border-box. See [ejfrancis' answer below](http://stackoverflow.com/a/14222863/422845), and see [this article](https://www.paulirish.com/2012/box-sizing-border-box-ftw/). – jbyrd Apr 04 '17 at 12:44
  • Are you sure about the td in tables? In Chrome it still seems to add to the size. – Protector one Apr 24 '19 at 11:26
54

Another good solution is to use outline instead of border. It adds a border without affecting the box model. This works on IE8+, Chrome, Firefox, Opera, Safari.

(https://stackoverflow.com/a/8319190/2105930)

Community
  • 1
  • 1
chowey
  • 9,138
  • 6
  • 54
  • 84
  • 1
    It's great, but comparing with border, there is no "outline-left,...", not for my case. – Imskull Apr 06 '15 at 03:53
  • 2
    Then I recommend using `box-shadow` per [my other answer](http://stackoverflow.com/questions/12671898/outline-on-only-one-border/18841365#18841365) on a similar question. It doesn't have the same browser support, but that is less of an issue these days. – chowey Apr 06 '15 at 06:12
  • Thank you #chowey , just realized `box-shadow` can support one-side border as well, prefect solution. – Imskull Apr 06 '15 at 06:38
  • 1
    `border-color: transparent` has better cross-browser support --- see my answer... – Edward Newell Apr 30 '16 at 04:14
  • 2
    This comment's under-rated. It's a great way to get a border around an element without resizing it! – Sebastian Nemeth Jul 31 '16 at 14:33
38

I usually use padding to solve this issue. The padding will be added when the border is not there and removed when it is back. Example:

.good-border {
  padding: 1px;
}

.good-border:hover {
  padding: 0px;
  border: 1px solid blue;
}

enter image description here

See my code here: https://jsfiddle.net/3t7vyebt/4/

Tho
  • 23,158
  • 6
  • 60
  • 47
25

Try this

box-sizing: border-box;
Hoang Trung
  • 1,979
  • 1
  • 21
  • 33
7

Sometimes you don't want height or width to be affected without explicitly setting either. In that case, I find it helpful to use pseudo elements.

.border-me {
    position: relative;
}

.border-me::after {
    content: "";
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border: solid 1px black;
}

You can also do a lot more with the pseudo element so this is a pretty powerful pattern.

Jack Guy
  • 8,346
  • 8
  • 55
  • 86
  • 1
    I had a 1px border that I wanted to change to 2px, and the only way I could find to do that was by removing the `width` and `height` and adding a `bottom` and `left` property in addition to the `top` and `left`, all of which should be set to the opposite width of the original border (in my case -1px). Great hack though – Chase Sandmann Mar 26 '20 at 23:52
  • This was quite useful for me actually, and simpler than implementing inner div borders or other hacks. – Michael Flores Sep 15 '21 at 11:00
6

Just decrease the width and height by double of border-width

Sadat
  • 3,493
  • 2
  • 30
  • 45
6

You can do some fancy things with inset shadows. Example to put a border on the bottom of an element without changing its size:

.bottom-border {
  box-shadow:inset 0px -3px 0px #000;
}
Luke Taylor
  • 8,631
  • 8
  • 54
  • 92
2
.filter_list_button_remove {
    border: 1px solid transparent; 
    background-color: transparent;
}
.filter_list_button_remove:hover {
    border: 1px solid; 
}
peevo
  • 29
  • 1
  • 1
    I think it would be more helpful for the OP and further visitors,whenn you add some explaination for your intension. – Reporter Aug 11 '14 at 12:25
2

Try decreasing the margin size when you increase the border

arun
  • 87
  • 1
  • 2
  • 9
2

I needed to be able to "border" any element by adding a class and not affect its dimensions. A good solution for me was to use box-shadow. But in some cases the effect was not visible due to other siblings. So I combined both typical box-shadow as well as inset box-shadow. The result is a border look without changing any dimensions.

Values separated by comma. Here's a simple example:

.add_border {
    box-shadow:-1px 0 1px 1px rgba(0, 0, 0, 0.75), inset -1px 0 0 1px rgba(0, 0, 0, 0.75);
}

jsfiddle

Adjust for your preferred look and you're good to go!

Chris
  • 893
  • 10
  • 23
2

We can also use css calc() function

width: calc(100% - 2px);

subtracting 2px for borders

Rajeev Singh
  • 143
  • 10
2

You can try a box-shadow inset

something like this: box-shadow:inset 0px -5px 0px 0px #fff

adds a white 5px border to the bottom of the element without increasing the size

Mzard31
  • 29
  • 3
1

You can create the element with border with the same color of your background, then when you want the border to show, just change its color.

0

In case content of your div is rendered dynamically and you want to set its height, you can use a simple trick with outline:

button {
    padding: 10px;
    border: 4px solid blue;
    border-radius: 4px;
    outline: 2px solid white;
    outline-offset: -4px;
}

button:hover {
    outline-color: transparent;
}

Example here: https://codepen.io/Happysk/pen/zeQzaZ