I would like “This is label” text to stack right underneath the “Prefix Text”, while radio button to be aligned right next to “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 class="label-container">
    <input type="radio" />
    <div class="label-text text-spacing prefix">Prefix Text</div>
    <div class="label-text text-spacing">This is label</div>
</label>

2

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 class="label-container">
    <input type="radio" />
    <div>
      <div class="label-text text-spacing prefix">Prefix Text</div>
      <div class="label-text text-spacing">This is label</div>
    </div>
</label>

just use some transform.

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

2

// 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;
}

.label-container {
  /* while 'inline grid' (note the space) is a valid property-
     value, regardless of Chrome's claim to the contrary,
     I've changed the property-value to 'inline-grid' for
     compatibility with Chrome, Edge, etc: */
  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 class="label-container">
    <input type="radio">
    <div class="label-text text-spacing prefix">Prefix Text</div>
    <div class="label-text text-spacing">This is label</div>
  </label>
  <label class="label-container">
    <input type="radio">
    <div class="label-text text-spacing prefix">Prefix Text</div>
    <div class="label-text text-spacing">This is label</div>
  </label>
  <label class="label-container">
    <input type="radio">
    <div class="label-text text-spacing prefix">Prefix Text</div>
    <div class="label-text text-spacing">This is label</div>
  </label>
</main>

JS Fiddle demo.

2