Home > Enterprise >  How do you make the Highlighted Area for a ContentEditable box larger?
How do you make the Highlighted Area for a ContentEditable box larger?

Time:10-07

I'm building a UI that uses contentEditable elements to input data into a model.

At the moment, when you select the element, the box automatically highlights the box's current input only, see below:

enter image description here

This is an issue as it can sometimes hide the cursor. I would like to increase the default size of the highlighted box to something like 20px, however, adding a min-width style to each element doesn't seem to make a difference to the size of the highlighted box.

What styles do I have to set/ what do I have to change to make this highlighted box larger?

Please see a code snippet of my current solution below:

const update_display = (id) => {
    const value = document.querySelector(`#${id}_input`).value;
    document.querySelector(`#${id}_display`).innerText = value;
};

const displays = document.querySelectorAll("label a");

displays.forEach((display) => {
      display.style.marginRight = "5px";
      display.style.marginLeft = "5px";
    });
 
displays.forEach((display) => {
      display.addEventListener("keydown", (event) => {
        if (event.key === 'Enter') {
            event.preventDefault()
        }
      })
    });
<label >E_1: <a id="E1_display" contenteditable="true">0.85</a></label>
<input
    id="E1_input"
    type="range"
    
    oninput="update_display('E1');run_surrogate()"
    min="0.7"
    max="1.0"
    step="0.01"
/>

CodePudding user response:

You could just add padding to the anchor element (label a).

[I am not sure why you have an a element here, but as you have that is what it being styled).

const update_display = (id) => {
    const value = document.querySelector(`#${id}_input`).value;
    document.querySelector(`#${id}_display`).innerText = value;
};

const displays = document.querySelectorAll("label a");

displays.forEach((display) => {
      display.style.marginRight = "5px";
      display.style.marginLeft = "5px";
    });
 
displays.forEach((display) => {
      display.addEventListener("keydown", (event) => {
        if (event.key === 'Enter') {
            event.preventDefault()
        }
      })
    });
label a {
  padding: 10px;
  
}
<label >E_1: <a id="E1_display" contenteditable="true">0.85</a></label>
<input
    id="E1_input"
    type="range"
    
    oninput="update_display('E1');run_surrogate()"
    min="0.7"
    max="1.0"
    step="0.01"
/>

CodePudding user response:

I'm adding this answer in case someone else has my exact use case.

I wanted to make the box 20px wide so the cursor was always viewable. Rather than set a width on the box, I have managed to make the cursor viewable by changing marginRight to paddingRight. As you can see, in the updated code below, the cursor is viewable in all cases.

const update_display = (id) => {
    const value = document.querySelector(`#${id}_input`).value;
    document.querySelector(`#${id}_display`).innerText = value;
};

const displays = document.querySelectorAll("label a");

displays.forEach((display) => {
      display.style.paddingRight = "5px";
      display.style.paddingLeft = "5px";
    });
 
displays.forEach((display) => {
      display.addEventListener("keydown", (event) => {
        if (event.key === 'Enter') {
            event.preventDefault()
        }
      })
    });
<label >E_1: <a id="E1_display" contenteditable="true">0.85</a></label>
<input
    id="E1_input"
    type="range"
    
    oninput="update_display('E1');run_surrogate()"
    min="0.7"
    max="1.0"
    step="0.01"
/>

CodePudding user response:

<a> is an inline element, so properties such as width and height have no affect. While display: inline-block is a viable solution, display: inline-flex makes aligning content easier. In Figure I is a part of the HTML of the example based on your OP. Figure II is the CSS applied to the HTML of Figure I.

Figure I

<label >E_1: 
  <a href="#" id="E1_display" name="display"  contenteditable>0.85</a>
</label>
<!-- Range is wrapped in a <label> -->
<label >
  <input id="E1_range" name="range"  min="0.7" max="1.0" step="0.01" value="0.85">
</label>

Figure II

.form-display {
  /* inline-block   flex 
     Explicit width and height applies
     Able to set vertical and horizontal position on content
  */
  display: inline-flex; 
  /* Content is vertically centered */
  align-items: center;
  /* ch is the width of a zero: "0" */
  min-width: 3.5ch;
  height: 26px;
  /* rem is equal to the default font-size found on <html> */
  margin: 0 0.5rem;
  padding: 0 1ch;
  /* Needed because href="#" is added to each <a> - href allows <a>
     to be recognized and collected as a live HTMLCollection via 
     document.links
  */
  color: black;
  /* As previous comment */
  text-decoration: none;
}

.form-label {
  display: inline-flex;
  align-items: center;
  margin-bottom: 0.75rem
}

The rest of the changes are not required, they are optional but strongly recommended.

const main = document.forms.main;
const displays = Array.from(document.links);

displays.forEach((display) => {
  display.addEventListener("keydown", function(event) {
    if (event.key === 'Enter') {
      event.preventDefault()
    }
  });
});

main.addEventListener("input", function(event) {
  const fc = this.elements;
  if (event.target !== this) {
    if (event.target.name === "range") {
      const id = event.target.id.slice(1, 2);
      const dis = document.getElementById("E"   id   "_display");
      dis.textContent = event.target.value;
    }
    if (event.target.name === "display") {
      const id = event.target.id.slice(1, 2);
      const rng = fc["E"   id   "_range"];
      rng.value = event.target.textContent;
    }
  }
});
html {
  font: 300 2ch/1.15 "Segoe UI";
}

#main {
  display: grid;
  grid-template-columns: 1fr 2fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  justify-items: stretch;
  align-items: stretch
}

.form-display {
  display: inline-flex;
  align-items: center;
  min-width: 3.5ch;
  height: 26px;
  margin: 0 0.5rem;
  padding: 0 1ch;
  color: black;
  text-decoration: none;
}

.form-label {
  display: inline-flex;
  align-items: center;
  margin-bottom: 0.75rem
}
<form id="main">
  <label >E_1: <a href="#" id="E1_display" name="display"  contenteditable>0.85</a></label>
  <label ><input id="E1_range" name="range"  type="range" min="0.7" max="1.0" step="0.01" value="0.85" /></label>

  <label >E_2: <a href="#" id="E2_display" name="display"  contenteditable>0.95489</a></label>
  <label ><input id="E2_range" name="range"  type="range" min="0.7" max="1.0" step="0.01" value="0.95489" /></label>

  <label >E_3: <a href="#" id="E3_display" name="display"  contenteditable>0.8</a></label>
  <label ><input id="E3_range" name="range"  type="range" min="0.7" max="1.0" step="0.01" value="0.8" /></label>
</form>

  • Related