简体   繁体   中英

Extra pixels when element is inline

I am struggling to understand how the calculation of width/height in inline elements works. My question is very similar to this Extra pixels are being added to the span element yet slightly different.

There is a div element of size 50x50. Within the div, there is a span with padding 15px. The span contains SVG circle of size 20x20.

So there are three use cases:

  1. Only div is a block

    • div - size 50x50 ✔️
    • span - size: 50x47 ❌ where are those three pixels?
    • svg - size: 20x20 ✔️
  2. div and span is a block

    • div - size 50x50 ✔️
    • span - size: 50x54 ❌ where do these 4 pixels come from?
    • svg - size: 20x20 ✔️
  3. eveything is a block

    • div - size 50x50 ✔️
    • span - size: 50x50 ✔️
    • svg - size: 20x20 ✔️

 span { /* display: block; */ padding: 15px; } div { height: 50px; width: 50px; } svg { /* display: block; */ height: 20px; width: 20px; }
 <div> <span> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> </div>

CodePen is available here .

Note: I tried it in the latest Chrome but I think it will be the same everywhere. It's probably just some fundamental thing I am missing. :)

Your second case is covered here: Image inside div has extra space below the image . Due to the default alignment you will have extra space under your SVG. This can be fixed by adding display:block like you discovered or by adding vertical-align:top which is more logical as solution:

 span { display: block; padding: 15px; outline:1px solid green; } div { height: 50px; width: 50px; margin:30px; outline:1px solid blue; } svg { height: 20px; width: 20px; outline:1px solid red; }
 <div> <span> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> </div> <div> <span> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="vertical-align:top;" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> </div>

Your first case is a bit tricky because it has nothing to do with the SVG or the width/height you are setting. It's all about font metrics.

To simplify let's remove the div around and consider different SVG inside the same span and without padding:

 span { border: 1px solid green; margin:0 10px; } svg { outline: 1px solid red; }
 <span> <svg viewBox="0 0 24 24" height="20" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="30" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="50" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="200" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span>

Notice how the span has always the same height whataver the SVG inside due to the nature of inline element. Let's increase the font-size

 span { border: 1px solid green; margin:0 10px; } svg { outline: 1px solid red; } body { font-size:40px; }
 <span> <svg viewBox="0 0 24 24" height="20" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="30" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="50" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span> <span> <svg viewBox="0 0 24 24" height="200" xmlns="http://www.w3.org/2000/svg" > <circle strokeLinecap="butt" strokeDasharray="64" cx="12" cy="12" r="9" /> </svg> </span>

The span are now bigger in height and the SVG are kept the same. You will also note the small gap at the bottom of the SVG due to the alignment I explained previously. Try to add font-size:0 and see the result.

As you can see the height of your span has nothing to do with the SVG. To that height, you add the vertical padding to get the final height. In your case, the height was 17px and adding the padding you will have 47px which is close to 50px but there is no relation with.

Note that you may get a different result than 47px if you test in different browsers/OS since the font will not for sure be the same and the initial height can vary.

If you check the speficiation you can read:

The 'height' property does not apply. The height of the content area should be based on the font ...

The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area,

Making the span block element will change this behavior and you will have a more intuitive result as you noticed in your last example: 2*15px of padding + 20px of SVG height.

Related question with more detail in order to understand how the height of element are calculated: How to determine height of content-box of a block and inline element

Another related question: Can specific text character change the line height?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM