Home > Blockchain >  How to properly scale width of SVG parent element in flexbox?
How to properly scale width of SVG parent element in flexbox?

Time:11-18

I'm currently trying to create a navbar for my website. The navbar is implemented using a ul container which is set to display: flex. Most of the items inside this flexbox are li tags containing anchor elements, but the first li contains an svg (a logo).

I'm trying to get the svg to responsively scale to the same height as the anchor elements by utilizing the implicit align-items: stretch of the ul. I would like the width to be automatically calculated using the original aspect ratio of the svg and the height.

I was able to get the svg to scale to the correct height by adding height: 100% to itself and its parent <a> tag. This has had the unintended side effect of making the parent li have a width of 0. This causes the flexbox to space the elements incorrectly. I've tried in Chrome and Firefox and had the same result regardless, so it seems likely this is intended functionality. I've attached a code snippet below showing the behavior.

Can someone help explain to me how I can fix this without requiring hard-coded values and still fulfilling the requirements above?

nav>ul {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: stretch;
    list-style: none;
    gap: 1em;
}

nav>ul>li {
    display: inline-block;
    text-align: center;
}

nav>ul>li>a {
    display: inline-block;
    text-decoration: none;
    padding: 0;
}

nav>ul>li>a:not(.logo-container>a) {
    color: white;
    background-color: gray;
    padding: 2em;
}

.logo-container>a {
    height: 100%;
}

.nav-logo {
    height: 100%;
}
<body>
  <header>
    <nav>
      <ul>
        <li >
          <a href="index.html">
            <svg  id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 164.81 281"><defs><style>.b{fill:#4098ff;}.c{fill:#1463b2;}.d{fill:#0b2c54;}</style></defs><path  d="M1.96,47.61v92.87l53.63,30.95v61.93l-26.8-15.49v-30.92L1.99,171.46v61.93l80.44,46.44V94.05L1.96,47.61Zm53.63,92.9l-26.8-15.49v-30.98l26.8,15.49v30.98Z"/><polygon  points="28.79 186.95 55.59 171.46 28.79 155.97 1.96 171.46 28.79 186.95"/><polygon  points="28.79 217.9 55.59 202.41 55.59 171.46 28.79 186.95 28.79 217.9"/><polygon  points="55.59 233.39 55.59 202.41 28.79 217.9 55.59 233.39"/><polygon  points="28.79 125.03 55.59 109.54 28.79 94.05 28.79 125.03"/><polygon  points="55.59 140.51 55.59 109.54 28.79 125.03 55.59 140.51"/><path  d="M82.42,94.05v185.78l26.8-15.49v-92.87l53.63-30.95V47.61l-80.44,46.44Zm53.6,30.98l-26.8,15.49v-30.95l26.8-15.49v30.95Z"/><polygon  points="109.22 140.51 136.03 125.03 109.22 109.54 109.22 140.51"/><polygon  points="136.03 94.05 136.03 125.03 109.22 109.54 136.03 94.05"/><polygon  points="1.96 47.61 82.42 94.05 162.86 47.61 82.42 1.17 1.96 47.61"/></svg>
          </a>
        </li>
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About</a></li>
        <li><a href="contact.html">Contact</a></li>
      </ul>
    </nav>
  </header>
</body>

CodePudding user response:

1st solution. Here SVG image content must be slightly changed - f.e. '#' must be changed on '#'

nav>ul {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: stretch;
    list-style: none;
    gap: 1em;
}

nav>ul>li {
    display: inline-block;
    text-align: center;
}

nav>ul>li>a {
    display: inline-block;
    text-decoration: none;
    padding: 0;
}

nav>ul>li>a:not(.logo-container>a) {
    color: white;
    background-color: gray;
  opacity: 0.5;
    padding: 2em;
}

.logo-container {
  padding: 2em 0;
  background-repeat: no-repeat;
  background-position: center;
  background-image: 
        url("data:image/svg xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 164.81 281'><path fill='#0b2c54' d='M1.96,47.61v92.87l53.63,30.95v61.93l-26.8-15.49v-30.92L1.99,171.46v61.93l80.44,46.44V94.05L1.96,47.61Zm53.63,92.9l-26.8-15.49v-30.98l26.8,15.49v30.98Z'/><polygon fill='#4098ff' points='28.79 186.95 55.59 171.46 28.79 155.97 1.96 171.46 28.79 186.95'/><polygon fill='#1463b2' points='28.79 217.9 55.59 202.41 55.59 171.46 28.79 186.95 28.79 217.9'/><polygon fill='#4098ff' points='55.59 233.39 55.59 202.41 28.79 217.9 55.59 233.39'/><polygon fill='#1463b2' points='28.79 125.03 55.59 109.54 28.79 94.05 28.79 125.03'/><polygon fill='#4098ff' points='55.59 140.51 55.59 109.54 28.79 125.03 55.59 140.51'/><path fill='#1463b2' d='M82.42,94.05v185.78l26.8-15.49v-92.87l53.63-30.95V47.61l-80.44,46.44Zm53.6,30.98l-26.8,15.49v-30.95l26.8-15.49v30.95Z'/><polygon fill='#4098ff' points='109.22 140.51 136.03 125.03 109.22 109.54 109.22 140.51'/><polygon fill='#0b2c54' points='136.03 94.05 136.03 125.03 109.22 109.54 136.03 94.05'/><polygon fill='#4098ff' points='1.96 47.61 82.42 94.05 162.86 47.61 82.42 1.17 1.96 47.61'/></svg>");    
}

i {
  padding: 2em;
}
<body>
  <header>
    <nav>
      <ul>
        <li id="logo" >
          <a href="index.html">
            <i></i>
          </a>
        </li>
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About</a></li>
        <li><a href="contact.html">Contact</a></li>
      </ul>
    </nav>
  </header>
</body>

CodePudding user response:

2nd solution. Here no need to change SVG content as on my 1st solution. Just copy and paste into JS var.

var mySVG = '<svg  id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 164.81 281"><defs><style>.b{fill:#4098ff;}.c{fill:#1463b2;}.d{fill:#0b2c54;}</style></defs><path  d="M1.96,47.61v92.87l53.63,30.95v61.93l-26.8-15.49v-30.92L1.99,171.46v61.93l80.44,46.44V94.05L1.96,47.61Zm53.63,92.9l-26.8-15.49v-30.98l26.8,15.49v30.98Z"/><polygon  points="28.79 186.95 55.59 171.46 28.79 155.97 1.96 171.46 28.79 186.95"/><polygon  points="28.79 217.9 55.59 202.41 55.59 171.46 28.79 186.95 28.79 217.9"/><polygon  points="55.59 233.39 55.59 202.41 28.79 217.9 55.59 233.39"/><polygon  points="28.79 125.03 55.59 109.54 28.79 94.05 28.79 125.03"/><polygon  points="55.59 140.51 55.59 109.54 28.79 125.03 55.59 140.51"/><path  d="M82.42,94.05v185.78l26.8-15.49v-92.87l53.63-30.95V47.61l-80.44,46.44Zm53.6,30.98l-26.8,15.49v-30.95l26.8-15.49v30.95Z"/><polygon  points="109.22 140.51 136.03 125.03 109.22 109.54 109.22 140.51"/><polygon  points="136.03 94.05 136.03 125.03 109.22 109.54 136.03 94.05"/><polygon  points="1.96 47.61 82.42 94.05 162.86 47.61 82.42 1.17 1.96 47.61"/></svg>';
var mySVG64 = window.btoa(mySVG);
document.getElementById('logo').style.backgroundImage = "url('data:image/svg xml;base64,"   mySVG64   "')";
nav>ul {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: stretch;
    list-style: none;
    gap: 1em;
}

nav>ul>li {
    display: inline-block;
    text-align: center;
}

nav>ul>li>a {
    display: inline-block;
    text-decoration: none;
    padding: 0;
}

nav>ul>li>a:not(.logo-container>a) {
    color: white;
    background-color: gray;
  opacity: 0.5;
    padding: 2em;
}

.logo-container {
  padding: 2em 0;
  background-repeat: no-repeat;
  background-position: center;
}

i {
  padding: 2em;
}
<body>
  <header>
    <nav>
      <ul>
        <li id="logo" >
          <a href="index.html">
            <i></i>
          </a>
        </li>
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About</a></li>
        <li><a href="contact.html">Contact</a></li>
      </ul>
    </nav>
  </header>
</body>

  • Related