htmlcsshover

Changing the position a little on hover in CSS


that's my first time to asking, so sorry if I'm not asking it clearly. I'm working with HTML and CSS and I don't know why when I set a hover for a div to make a border around it, border appears but the div move a little bit to bottom, and that's my problem, Does anyone else have it? I'll put a photo of CSS code and I will be glad if you can help me, thanks.

`.navbar{
    height: 48.48px;
    width: 70px;
    float: right;
    margin: 10px 5.57%;
    color: white;
    text-align: center;
    cursor: pointer;
    box-sizing: border-box;
}
.text1{
    color: white;
    cursor: pointer;
}
.navbar :hover{
    border: 1.5px white solid;
    border-radius: 10px;
}

I tried to make a border around a div when cursor is on it with hover, although the border appears, the div moves a little bit.

I even tried box sizing but it didn't work


Solution

  • Using borders to indicate state comes with some caveats, mainly that the border doesn't just sort of float around the element, it gets added to it's dimensions, which will as a result appear to move a bit upon hovering over it. There are a few simple solutions for this. Which you choose can depend on the context.

    Demo of all of the below solutions: https://jsfiddle.net/r5eafkv9/

    Note: I'm using buttons in my examples, but this all applies regardless of what element you're styling. Could be a hyperlink, a div, or something else.

    1. Use outline instead of border

    Borders are drawn within the bounds of the element, and add to it's final dimensions (at least in the default CSS box model; we'll get back to this*). Outlines, however, are drawn around the element, and can also overlap rather than nudging adjacent elements. You can sort of think of them as absolutely positioned relative to the button (or whatever the element is). They do not interact with the box model when it comes to dimensions/positioning.

    .btn.outline:hover {
      outline: 4px darkgreen solid;
    }
    

    2. Transparent default border

    Add a transparent border to the default state. As long as it's the same width as the one applied to the :hover state, the dimensions will be the same.

    .btn.transparent {
      border: 4px transparent solid;
    }
    .btn.transparent:hover {
      border: 4px darkgreen solid;
    }
    

    3. *Set box-sizing to border-box

    This tells the CSS box model to account for padding and borders in it's calculations for elements' width and height, as opposed to the default CSS box model (content-box), in which case, adding padding or borders to an element will add to its final on-screen dimensions, and need to be accounted for.

    .btn.borderbox {
      box-sizing: border-box;
    }
    .btn.borderbox:hover {
      box-sizing: border-box;
      border: 4px darkgreen solid;
    }
    

    General advice

    1. I can't express the importance of understanding the CSS box model. It's really not that complicated, and learning it up front will save you endless hours that would otherwise be spent learning it by trial when you get stuck on cases like these where the box model comes into play. You should also know that this is the simplest version of the answer to the question "why is this like this?" being "because the box model".

    2. Just a personal recommendation, not necessarily gospel, but the first lines of nearly every stylesheet I ever write are as follows:

        * {
          margin: 0px;
          padding: 0px;
          box-sizing: border-box;      
        }
    

    Zeroing out margin and padding is optional, but if you're a control freak like I am, you'll appreciate the blank slate. The more important bit (to me at least) is the box-sizing: border-box rule, which simplifies most of the complexity of the box model away. You want a div to be 300px wide?... width: 300px; Done. Not always the case with the default behaviour (box-sizing: content-box).

    1. I highly recommend you hit up Mozilla's web docs when you're trying to understand some seemingly weird behaviour. StackOverflow is a great resource (understatement of the year), but there's nothing like thorough, structured documentation to really understand why something is behaving unexpectedly, as opposed to just finding the incantation to make it stop. And while I'm harping on the subject, here's the entry on the CSS box model.

    Happy coding!

    Quick Tangent

    Regarding Paulie_D's comment about half pixels: They may just get rounded off a lot of the time, but they are 100% valid CSS. And when hardware acceleration is involved (translate3d, for example), they can very well have an actual effect, other than just being rounded to a full pixel. Whether or not it's wise to use them explicitly is another question (it can result in elements appearing blurry when they land on a half pixel, for example, and again, they can also just be rounded (usually up, I believe)).