skip to Main Content

I need to align input in a div. If the div clicked then the input should be shown otherwise a span should be shown.

My code:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .cell-wrapper {
        display: inline-flex;
        align-items: center;
        width: 100px;
        border: 1px solid #ccc;
        padding: 0;
        margin: 0;
      }
      .cell-wrapper,
      .cell-wrapper input {
        height: 50px;
        font-size: 15px;
      }

      .cell-wrapper span {
        padding: 0 6px;
      }

      .cell-wrapper input {
        width: 100%;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <div id="root">
        <div>
            <table-cell v-for="col in cols" :key="col"/>
        </div>
    </div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
      const TableCell = {
        template: /*html*/ `
        <div @click="editing = true" class="cell-wrapper">
            <input
                v-if="editing"
                v-model="val"
                class="col"
                @blur="editing = false"
                @vue:mounted="({ el }) => el.focus()"
            />
            <span v-else>{{ val }}</span>
        </div>
        `,
        setup() {
          const editing = Vue.ref(false)
          const val = Vue.ref('')
          return {
            val,
            editing
          }
        }
      };
      const app = Vue.createApp({
        setup() {
          const cols = Vue.ref(5)
          return {
            cols,
          }
        }
      })
      app.component('table-cell', TableCell)
      app.mount('#root')
    </script>
  </body>
</html>

This code produce:

first render of the page

And when I change the input value, rendered page become (the expected value: all table-cell should be aligned in horizontally):

unexpected rendered page

I know that the problem is CSS proble but I don’t understand the reason.

2

Answers


  1. You can vertically align the elements by setting the parent div to display: flex

    #root > div {
        display: flex;
        align-items: center;
    }
    
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          .cell-wrapper {
            display: inline-flex;
            align-items: center;
            width: 100px;
            border: 1px solid #ccc;
            padding: 0;
            margin: 0;
          }
          .cell-wrapper,
          .cell-wrapper input {
            height: 50px;
            font-size: 15px;
          }
    
          .cell-wrapper span {
            padding: 0 6px;
          }
          
          #root > div {
            display: flex;
            align-items: center;
          }
    
          .cell-wrapper input {
            width: 100%;
            box-sizing: border-box;
          }
        </style>
      </head>
      <body>
        <div id="root">
            <div>
                <table-cell v-for="col in cols" :key="col"/>
            </div>
        </div>
        <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
        <script>
          const TableCell = {
            template: /*html*/ `
            <div @click="editing = true" class="cell-wrapper">
                <input
                    v-if="editing"
                    v-model="val"
                    class="col"
                    @blur="editing = false"
                    @vue:mounted="({ el }) => el.focus()"
                />
                <span v-else>{{ val }}</span>
            </div>
            `,
            setup() {
              const editing = Vue.ref(false)
              const val = Vue.ref('')
              return {
                val,
                editing
              }
            }
          };
          const app = Vue.createApp({
            setup() {
              const cols = Vue.ref(5)
              return {
                cols,
              }
            }
          })
          app.component('table-cell', TableCell)
          app.mount('#root')
        </script>
      </body>
    </html>
    Login or Signup to reply.
  2. Try below CSS code i hope solve your issue:

    .cell-wrapper {
          align-items: center;
          width: 100px;
          border: 1px solid #ccc;
          padding: 0;
          margin: 0;
        }
    
        .cell-wrapper,
        .cell-wrapper input {
          height: 50px;
          font-size: 15px;
          display: flex;
          text-align: center;
        }
    
        .cell-container {
          display: flex;
          flex-direction: row;
        }
    
        .cell-wrapper span {
          padding: 0 6px;
          width: 100%;
        }
    
        .cell-wrapper input {
          width: 100%;
          box-sizing: border-box;
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search