Flex space around does not respond - html

HTML CODES
I cannot use 'space-around' property.It does not work even if I wrap tag 'a' and 'svg' with div.How can I solve this problem?
.container {
width: 300px;
}
.title {
display: flex;
flex-direction: space-around;
}
<div class="container">
<div class="title">
Library
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bookmark"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>
</div>
</div>

As #Sfili mentioned in the comments, those styles correspond with justify-content and not flex-direction. space-around is supposed to give the elements equal spacing on both sides. So if you had a 300px container. space-around would look like so:
space-between on the other hand will space the elements on both ends of the parent. So it would space both items to the start and end of their parent. See below.
.container {
width: 300px;
outline: solid black 1px;
}
.title {
display: flex;
justify-content: space-between;
}
<div class="container">
<div class="title">
Library
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bookmark"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>
</div>
</div>

Related

CSS - inline SVG interferes with line-height?

I'm struggling to understand the the following css behavior. Maybe I'm missing something important because this actually seems like a simple scenario to me. Consider the following example:
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Text
</div>
Because container has line-height: 20px set, I'd expect it to be 20px high. At least this is the case if it only contains text. With the svg however it is suddenly 24px high, even though the svg is 20px high, as expected because of height=1em. Also the "Text" has a height of 23px, even though I'd expect it to be 20px.
Interestingly, if I set container's line-height to something like 30px, it behaves as expected: container is now 30px high.
Can you help me understand why container is not 20px high? Or is line-height simply not easily predictable once the container contains other elements than just plain text? Thank you!
There are two things going on in your demo that are affecting the height of div.container. First, line-height isn't an explicit, fixed height: it specifies the minimum height of line boxes within div.container in your case. Since line-height is a minimum, it can grow if something inside it causes it to grow.
That leads to the SVG: it has a default vertical-align of baseline, which aligns it to the baseline of div.container, and, due to its height, causes the height of div.container to grow to accommodate it. By changing vertical-align of the SVG to something else so it fits within your 20px line-height, you can make it fit.
I've added a few different vertical-align props to your demo so you can see how alignment affects height. In general, bottom and top align the svg to the bottom and top of the line, respectively, which, given the SVG's 20px height, keep it within the line-height. However, if you really, really need div.container to be 20px height, height or max-height are probably better bets.
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
margin-bottom: 1em;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: baseline (24px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:middle">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: middle (~22px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:bottom">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: bottom (20px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:top">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: top (20px)
</div>
This gets all heights to 20px using flex, align-items: center; and line-height: 1rem;:
.container {
background-color: lime;
font-size: 20px;
line-height: 1rem;
display: flex;
align-items: center;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Text
</div>

SVG fill / stroke

Need some help with filling my svg with color on hover.
On the left I have my test svg, on the right - the result I want on hover.
How to fill with color on hover only gray lines and let the space inside be transparent (empty)?
(that's strange that space inside is fillinbg with color, because there is no svg content there)
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover {
fill: #40bfff;
stroke:#40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#9098B1" stroke="#9098B1" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#9098B1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<!-- changing stroke and fill to color i need -->
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#40bfff" stroke="#40bfff" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#40bfff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
</div>
All you have to do to change the wheel fill colour is add a second rule targetting the wheels.
Note: The SVG below is exactly the same as your original one. Except that I have reformatted it a little, and added a viewBox so that we can scale it up to see the wheels. I wanted to show that you can style the SVG how you want without having to change the SVG.
svg {
/* just here to make the svg large enough to see the wheel centres */
width: 200px;
height: 200px;
}
svg:hover path {
stroke: #40bfff;
}
/* Target the first path (the wheels) */
svg:hover path:nth-child(1) {
fill: #40bfff;
}
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z"
fill="#9098B1" stroke="#9098B1"
stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375"
stroke="#9098B1"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
try this:
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover path {
stroke: #40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#9098B1" stroke="#9098B1" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#9098B1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<!-- changing stroke and fill to color i need -->
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#40bfff" stroke="#40bfff" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#40bfff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
</div>
Put all your stroke & fill attributes into the svg element since that's where your hover is set.
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover {
fill: none;
stroke: #40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" stroke="#9098B1" fill-opacity="0" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round">
<path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" />
<path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375"/>
</svg>
</div>

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:
Only div is a block
div - size 50x50 ✔️
span - size: 50x47 ❌ where are those three pixels?
svg - size: 20x20 ✔️
div and span is a block
div - size 50x50 ✔️
span - size: 50x54 ❌ where do these 4 pixels come from?
svg - size: 20x20 ✔️
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?

How can I align svg circle in the middle of the div?

I need to make a circle emulating the button for closing the window in the Mac OS. But when I try to move it lower, svg's border cuts it off. How can I move the border to place the circle directly in the middle of the panel (vertically)?
JSFiddle: https://jsfiddle.net/sm6r0kvn/2/
<div class="panel">
<svg viewbox="0 0 20 17" width="20" heigth="50"><circle r="7" cx="14" cy="9.5" fill="#fc615e"/></svg>
</div>
You can set your viewbox like <svg viewbox="0 0 20 20" width="20" heigth="20"> and then set cx and cy 50%. If you want to center it in the panel vertically just make it a flexbox and add align-items: center - see demo below:
.block {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 550px;
min-width: 480px;
width: 80vw;
height: 200px;
background: black;
border-radius: 10px 10px 5px 5px;
}
.panel {
background-color: #e0e0e0;
border-radius: 5px 5px 0 0;
display: flex; /* added */
align-items: center; /* added */
}
.text {
color: white;
padding: 5px;
}
<div class="block">
<div class="panel">
<svg viewbox="0 0 20 20" width="20" heigth="20">
<circle r="7" cx="50%" cy="50%" fill="#fc615e"/>
</svg>
</div>
<div class="text">
Text here
</div>
</div>
This is because you are drawing your cicrcle outside of the svg viewbox. You can either use CSS to move whole svg box or make it larger
svg {
border: 1px blue solid;
}
.panel.moved {
margin-left: 100px;
}
<div class="panel">
<svg viewbox="0 0 20 20" width="200" heigth="200">
<circle r="10" cx="10" cy="10" fill="#fc615e"/>
</svg>
</div>
<div class="panel">
<svg viewbox="0 0 20 20" width="200" heigth="200">
<circle r="10" cx="20" cy="10" fill="#fc615e"/>
</svg>
</div>
<div class="panel">
<svg viewbox="0 0 30 20" width="300" heigth="200">
<circle r="10" cx="20" cy="10" fill="#fc615e"/>
</svg>
</div>
<div class="panel moved">
<svg viewbox="0 0 20 20" width="200" heigth="200">
<circle r="10" cx="10" cy="10" fill="#fc615e"/>
</svg>
</div>

SVG property vector-effect="non-scaling-stroke" still scales stroke

In SVG, I need the PATH stroke width to remain as is while viewBox property is changing. The SVG property vector-effect="non-scaling-stroke" should accomplish that but it is not working as it suppose to.
Can someone explain why in the code below (check the codepen.io) the stroke width still increases as viewbox changes? I would also appreciate a solution that makes strokes width constant regardless of viewbox.
https://codepen.io/anon/pen/eKQrYL
HTML
<div class="Item">
<div class="Item-graphic">
<svg id='scaling-stroke' width="200" height="200" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="2"/>
<path d="M25 15 L 25 35" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
<path d="M15 25 L 35 25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
</svg>
</div>
<span>
50 x 50 view box<br>
200 x 200 dimensions<br>
no vector effect
</span>
</div>
<div class="Item">
<div class="Item-graphic">
<svg id='non-scaling-stroke' width="200" height="200" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="2" vector-effect="non-scaling-stroke"/>
<path d="M25 15 L 25 35" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
<path d="M15 25 L 35 25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
</div>
</svg>
<span>
50 x 50 view box<br>
200 x 200 dimensions<br>
vector effect
</span>
</div>
CSS
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: #2196F3;
font-family: Helvetica, sans-serif;
font-weight: 300;
line-height: 1.5;
}
svg {
display: block;
margin: 0 auto;
}
.Item {
flex: 0 0 200px;
padding: 0 1rem;
color: rgba(#fff, 0.6);
font-size: 11px;
text-align: center;
}
.Item-graphic {
display: flex;
align-items: center;
height: 220px;
}
JS
n=1;inc=1;
cvb = function(){
vb = '' + n
vb += ' ' + n
vb += ' ' + 2*(25-n)
vb += ' ' + 2*(25-n)
$('#non-scaling-stroke').attr('viewBox', vb)
$('#scaling-stroke').attr('viewBox', vb)
n += inc;
if (n<=1 || n>=24) inc *= -1;
setTimeout(cvb, 100);
};
cvb()
It is a bug in Chrome. The bug report is here https://bugs.chromium.org/p/chromium/issues/detail?id=849080. It was fixed in Chrome version 68.0.3440.25.