0

I have a row of 3 inputs. One of them has label text placed above its input. I do not want this label text to interfere with the alignment of the inputs. Right now I'm using flexbox in my example. My hack/approach is to use position: absolute; on my optional label text to remove it from the flex flow so the inputs stay align. However, this creates a bit of spacing inconsistency when wrapping on smaller viewports. I've tried CSS grid as well but had issues where I was stuck writing a media query for every time I needed to wrap, which seemed worse than this. I would also like the solution to have no fixed widths/heights. As the elements and text can be dynamic. What is the best way to achieve this functionality that allows for a cleaner wrapping?

.container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.optionalContainer {
  position: relative;
  /*hack to container optional text*/
  padding: 20px 0;
}

.optional {
  position: absolute;
  top: 0;
  margin: 0;
}
<form class="container">
  <input required type="text"/>
  <div class="optionalContainer">
    <p class="optional">Optional:</p>
    <input type="text"/>
  </div>
  <input required type="text"/>
</form>

Example of what I'm shooting for at different viewports:

large

medium

small

anthony-dandrea
  • 2,583
  • 7
  • 26
  • 46
  • Can you show exactly your testcases? You can draw it with paint if you want. For example what should the graphical output if the `optionalContainer` is absent? How should it behave on smaller device? Can the HTML change? – aloisdg Nov 20 '22 at 00:49
  • Consider working with [required](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/required) and [placeholder](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text#placeholder) instead, which may make your life simpler. – Nils Lindemann Nov 20 '22 at 01:01
  • @aloisdg my test case is more or less exactly what my code sample does. But I don't want it be hacky using the `position: absolute` hack. Trying to see if there is a better way, perhaps using grid. Added screenshots for extra clarity if that helps. – anthony-dandrea Nov 20 '22 at 01:28
  • @NilsLindemann I'm aware of those attributes but they unfortunately have nothing to do with my styling quesiton. – anthony-dandrea Nov 20 '22 at 01:28
  • @anthony-dandrea OK, but I will keep the comment, as it may be useful for other readers. – Nils Lindemann Nov 20 '22 at 01:34

2 Answers2

0

Here is a solution avoid both positioning and the padding hack using flex with row-gap of the input-height:

:root {
  --input-height: 21.2px;
}

.container {
  display: flex;
  align-items: end;
  flex-wrap: wrap;
  row-gap: var(--input-height);
}
<form class="container">
    <input required type="text" />
  <div>
    <div>Optional:</div>
    <input type="text" />
  </div>
    <input required type="text" />
</form>
aloisdg
  • 22,270
  • 6
  • 85
  • 105
0

Here is a another solution which avoid both positioning and the padding hack using grid and a grid-template-columns hack:

:root {
  --input-width: 146.867px;
  --input-height: 21.2px;
}

.container {
  display: grid;
  /* wrapping hack from https://stackoverflow.com/a/43664701/1248177 */
  grid-template-columns: repeat(auto-fill, minmax(var(--input-width), 1fr));
  row-gap: var(--input-height);
  align-items: end;
}

.optionalContainer > input {
  box-sizing: border-box;
  width: 100%;
}
<form class="container">
  <input required type="text" />
  <div class="optionalContainer">
<div class="optional">Optional:</div>
<input type="text" />
  </div>
  <input required type="text" />
</form>
aloisdg
  • 22,270
  • 6
  • 85
  • 105