htmlcsssvgappendchildcreateelement

Why is there a gap between text and an SVG element?


I would like the text near the SVG icon but I can't achieve this. There is always big space between elements. Can you help me?

var tick = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-square-fill" viewBox="0 0 16 16"><path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm10.03 4.97a.75.75 0 0 1 .011 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.75.75 0 0 1 1.08-.022z"/></svg>'
var cross = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-exclamation-square-fill" viewBox="0 0 16 16"><path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6 4c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995A.905.905 0 0 1 8 4zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/></svg>'

const fragment = document.createElement('span')
fragment.style.display = 'flex'
const l1 = document.createElement("label")
l1.textContent = "HWjgvttgvyvytvhgvhgvhgvhtvytcytcytcytcytcyt";
l1.style.marging='0'
//l1.style.flex='auto'
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.innerHTML = tick
svg.style.marging='0'
//svg.style.flex='auto'

fragment.appendChild(svg)
fragment.appendChild(l1)

document.body.appendChild(fragment);

I tried flex, inline-block, grid as display properties


Solution

  • Use the devtools to inspect this and it will show you what is taking up the space. Take a look at this

    enter image description here

    You have an <svg> element as a string, and then you create a new svg element and put the <svg> string as the child content of that new element.

    Also you are setting style.marging where I assume you mean to set style.margin

    See the below changes. Instead of defining all those SVG element attributes in the string, you'll need to define them in code and set each one as an attribute. I've made a helper function that does this for you as long as you pass it the contents of the SVG element as a string. This also means you only need to save the <path> element as a string instead of the entire svg element as a string.

    var tickPath = '<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm10.03 4.97a.75.75 0 0 1 .011 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.75.75 0 0 1 1.08-.022z"/>'
    var crossPath = '<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6 4c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995A.905.905 0 0 1 8 4zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>'
    
    function createSvgEl(pathString){
      const ns = "http://www.w3.org/2000/svg";
      const svgEl = document.createElementNS(ns, "svg");
      svgEl.innerHTML = pathString
      svgEl.style.margin='0'
      //svgEl.style.flex='auto'
      svgEl.setAttribute("xmlns", ns);
      svgEl.setAttribute("width", 16);
      svgEl.setAttribute("height", 16);
      svgEl.setAttribute("fill", "currentColor");
      svgEl.setAttribute("class", "bi bi-check-square-fill");
      svgEl.setAttribute("viewBox", "0 0 16 16");
      
      return svgEl;
    }
    
    const wrapperEl = document.createElement('span')
    wrapperEl.style.display = 'flex'
    wrapperEl.appendChild(createSvgEl(tickPath))
    
    const labelEl = document.createElement("label")
    labelEl.textContent = "HWjgvttgvyvytvhgvhgvhgvhtvytcytcytcytcytcyt";
    labelEl.style.margin='0'
    //labelEl.style.flex='auto'
    wrapperEl.appendChild(labelEl)
    
    document.body.appendChild(wrapperEl);