Home > database >  Multi-line label for radio button
Multi-line label for radio button

Time:06-17

I would like "This is label" text to stack right underneath the "Prefix Text", while radio button to be aligned right next "Prefix Text". Is it possible to get this done by updating class for div element that contains "This is label" only? I would like to keep label-container class untouched if possible as I may add icon in front of "Prefix Text" so I will need display: inline-flex to wrap them up. https://codepen.io/Judoboy/pen/OJQqPEW?editors=1100

.label-container {
  display: inline-flex;
  justify-content: flex-start;
  align-items: center;
}

.label-text {
  display: flex;
  justify-items: center;
  align-items: center;
  height: 100%;
}

.prefix {
  font-weight: bold;
}

.text-spacing {
  padding-inline-start: 8px;
  padding-inline-end: 4px;
}
<label >
    <input type="radio" />
    <div >Prefix Text</div>
    <div >This is label</div>
</label>

CodePudding user response:

You can do this:

  • Wrap both Prefix Text and This is label with additional div.
  • Change align-items in .label-container class to start (you can keep display: inline-flex).

.label-container {
  display: inline-flex;
  justify-content: flex-start;
  align-items: start;
}

.label-text {
  display: flex;
  justify-items: center;
  align-items: center;
  height: 100%;
}

.prefix {
  font-weight: bold;
}

.text-spacing {
  padding-inline-start: 8px;
  padding-inline-end: 4px;
}
<label >
    <input type="radio" />
    <div>
      <div >Prefix Text</div>
      <div >This is label</div>
    </div>
</label>

CodePudding user response:

just use some transform.

.AlignmentFix {
  transform: translate(-100%, 17px);
}
<label >
    <input type="radio" />
    <div >Prefix Text</div>
    <div >This is label</div>
</label>

CodePudding user response:

// finding the only <button> element in the document, and binding
// an anonymous Arrow function as the event-handler for the 'click'
// event on that <button>:
document.querySelector('button').addEventListener('click', (e)=>{
  // we retrieve the first element in the document that matches
  // the selector supplied to document.querySelector():
    let original = document.querySelector('label.label-container'),
      // we then clone that node, and its descendant elements
      // with the Boolean true argument passed to Node.cloneNode():
        clone = original.cloneNode(true);
  // e.currentTarget is the element to which the anonymous function
  // was bound; from that element we navigate to the first ancestor
  // element that matches the selector and then append the 'clone'
  // to that <main> element:
  e.currentTarget.closest('main').append(clone);
});
/* overriding browser default layout calculations,
   and zeroing all margin and padding for cross-
   browser consistency: */
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* element added for layout purposes, to avoid changing the <body>
   element's styles in case of conflict with your real-world
   preferences: */
main {
  border: 1px solid #000;
  border-radius: 1em;
  display: flex;
  flex-flow: row wrap;
  gap: 0.5em;
  justify-content: space-between;
  margin-block: 1em;
  margin-inline: auto;
  padding: 0.5em;
  width: clamp(10rem, 60vw, 1000px);
}

/* styling the <button> to occupy the whole width, or a full
   'row': */
button:first-child {
  flex-basis: 100%;
  flex-grow: 1;
  padding-block: 0.5em;
}

/* using inline grid (though 'inline-grid' also works),
   to use grid layout within the <label> elements: */
.label-container {
  display: inline grid;
  /* here we create a grid-layout of two columns, and two
     rows with three 'cells'. The first cell is placed in
     the first column, and spans both rows. The other
     cells take only one 'cell' each. */
  grid-template-areas:
      "radio prefix"
      "radio text";
}

/* this selects <input> elements of 'type=radio' which
   are found within a parent that matches the
   '.label-container' selector; the use :where() - as
   opposed to :is() - avoids increasing selector
   specificity: */
:where(.label-container) input[type=radio] {
  /* this leaves the browser to calculate the preferred
     row to place the element, but specifies that the
     content must span two rows: */
  grid-row: span 2;
}

.label-text {
  display: flex;
  justify-items: center;
  align-items: center;
  height: 100%;
}

.prefix {
  font-weight: bold;
}

.text-spacing {
  padding-inline-start: 8px;
  padding-inline-end: 4px;
}
<!-- this element is purely for the wrapping, to supply padding and layout; obviously
     adjust to your preferences: --> 
<main>
  <!-- added a <button> to handle the addition of new <label> elements to demonstrate the layout -->
  <button>Add another &lt;label&gt; element</button>
  <label >
    <input type="radio">
    <div >Prefix Text</div>
    <div >This is label</div>
  </label>
  <label >
    <input type="radio">
    <div >Prefix Text</div>
    <div >This is label</div>
  </label>
  <label >
    <input type="radio">
    <div >Prefix Text</div>
    <div >This is label</div>
  </label>
</main>

JS Fiddle demo.

  • Related