'How to align two form input boxes with each other?

I have a modal with a form (using Bootstrap-Vue and Vue2). Each row has two fields. If user does not enter a valid value to the field, the state of the field returns false, making the box to be colored with red and add a message under the field. But I want both of the fields (in the same row) to be aligned with each other. The problem:

enter image description here

When I don't show an error, it looks good:

enter image description here

The code:


<div class="text-right">
  <div class="row">
    <div class="col-md-6">
      <div class="modal-label">שדה 1</div>
      <b-form-input
       :class="{ 'invalid-form-box': !stateField1(), 'modal-input': true}"
       v-model="course_number"
       type="number"
       placeholder="שדה 1"
       :trim="trimInput"/>
      <p v-if="!stateField1()" class="invalid-form-text">
        לא חוקי 1
      </p>
      <p v-if="!stateField2() && stateField1()" class="invalid-form-text"></p>
    </div>

    <div class="col-md-6">
      <div class="modal-label">שדה 2</div>
      <b-form-input
       :class="{ 'invalid-form-box': !stateField2(), 'modal-input': true}"
       v-model="score"
       type="number"
       placeholder="שדה 2"
       :trim="trimInput"/>
      <p v-if="!stateField2()" class="invalid-form-text">
        לא חוקי 2
      </p>
      <p v-if="!stateField1() && stateField2()" class="invalid-form-text"></p>
    </div>
  </div>
...
</div>

<style scoped>
  div {
    margin: auto 0;
    direction: rtl;
  }

  input {
    direction: rtl;
  }

  .modal-label {
    margin-bottom: 0.5rem;
  }

  .modal-input {
    margin-bottom: 0.5rem;
  }

  .modal-header .close {
    padding: 1rem 1rem !important;
    margin: -1rem auto -1rem -1rem !important;
  }
  
  .invalid-form-text {
    width: 100%;
    margin-top: 0.25rem;
    font-size: 80%;
    color: #dc3545;
  }

  .invalid-form-box:focus {
    border-color: #dc3545;
    box-shadow: 0 0 0 0.2rem rgb(220 53 69 / 25%);
    background-repeat: no-repeat;
  }

  .invalid-form-box {
    border-color: #dc3545;
    background-repeat: no-repeat;
  }
</style>

How can I make them aligned? I tried to replace <p> with <div>, <label> and <span>. Also tried to use <br>.



Solution 1:[1]

The shifting is caused by the margin: auto 0; rule in:

div {
  margin: auto 0; ? causes layout shift when error message appears
}

That rule sets the top and bottom margins of all divs to auto. Notice the vertical margins of the divs (div.col-md-6 and div.modal-label) when there is no error:

visualization of margins (without error)

And when there is an error, the outer margins collapse to make room:

visualization of margins (with error)

Solution

I think you were only trying to set the horizontal margins to 0. You can do that with:

div {
  margin-right: 0;
  margin-left: 0;
}

solution

demo

Solution 2:[2]

There are two ways you can achieve this. I recommend first one.

  1. Make 'invalid-form-text' tag position absolute and fix it's position where you want and that will remove this layout shift.

  2. If you are using flex use align-items: flex-start so when error appears alignment will align them to flex start and it will appear they are in same line. ( It should work but might not work due to other css conflicts- in case it didn't work just ask )

Solution 3:[3]

If you use BootstrapVue, you can do something like:

<b-row align-v="start">
  <b-col cols="6">
    // Whatever goes in your first column
  </b-col>
  <b-col cols="6">
    // Whatever goes in your second column
  </b-col>
</b-row>

Solution 4:[4]

You can add this to parent div.

display: flex;
align-items: center;
justify-content: center;

This will put both inputs aligned next each other.

Solution 5:[5]

I believe this line of code is responsible for showing or hiding error

<p v-if="!stateField2()" class="invalid-form-text">

You can have this p below each textbox

And your invalid-form-text class can be like this

.invalid-form-text{
     visibility: hidden;
}

The point here is that if you show hide elements with visibility style then element will still occupy space in DOM no matter they are visible or hidden, and it wont disturb alignments of elements

Solution 6:[6]

One approach is to make the .invalid-form-text element a height of 0px and make sure it's overflow is set to visible if not already.

If you need to add some margin to the element you could change your existing margin to transform: translateY which prevents it from affecting other elements in the dom layout.

.invalid-form-text{
   height: 0;
   overflow: visible;
   margin: 0px;
   transform: translateY(0.25rem);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tony19
Solution 2 prograk
Solution 3 Dharman
Solution 4 DarkForest
Solution 5 Surinder Singh
Solution 6 Kyle