unwanted whited space while appending element using class in jquery

Below code creates unwanted space before value1 and value2 while appending element using .append() of jquery and based on class

I am trying to add indicator on every table and tried different options of .before() , append() but prepend is close but white space is causing issue

$(".step").prepend('<span class="stepPos">1</span>')
table, tr, td, th{
  border:1px solid black;
  padding:0px !important;
}

.stepPos{
 position:relative;
 left:-15px;
}


body{
  padding:20px
}
<table>
<tr>
  <th >heading</th>
  </tr>
  <tr>
    <td class="step">value</td>
  </tr>
</table>
<br>
<table>
<tr>
  <th >heading2</th>
  </tr>
  <tr>
    <td class="step">value2</td>
  </tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Answers 1

  • When you use position: relative and a negative offset, the space for the element (in its original position) is still reserved within its parent container, all you're doing is moving the element relative to that space (which can be a bit surprising). The space before "value" and "value2" is where the 1 would be if you hadn't moved it with left: -15px.

    This should help visualize that:

    .x {
      background: #ccc;
    }
    .offset {
      position: relative;
      left: -15px;
    }
    .container {
      position: relative;
      border: 1px solid green;
      margin-left: 10px;
    }
    .spacer {
      height: 1em;
    }
    <div class="container">
      <span class="x">x</span>
      <span>y</span>
    </div>
    <div class="spacer"></div>
    <div class="container">
      <span class="x offset">x</span>
      <span>y</span>
    </div>

    You can see how the space for the x is still reserved in its original location; when we offset where the x is, we just offset it relative to that reserved space, without changing where that reserved space is.

    To avoid having that space taken up by the stepPos elements, make them position: absolute instead. To make sure they're positioned relative to their parent td, you'll also need to add position: relative to the tds so they're offset parents for their content.

    td.step {
      position: relative;
    }
    
    .stepPos{
      position:absolute;
      left:-15px;
    }
    

    Example:

    $(".step").prepend('<span class="stepPos">1</span>');
    table, tr, td, th{
      border:1px solid black;
      padding:0px !important;
    }
    
    td.step {
      position: relative;
    }
    
    .stepPos{
      position:absolute;
      left:-15px;
    }
    
    body{
      padding:20px
    }
    <table>
    <tr>
      <th >heading</th>
      </tr>
      <tr>
        <td class="step">value</td>
      </tr>
    </table>
    <br>
    <table>
    <tr>
      <th >heading2</th>
      </tr>
      <tr>
        <td class="step">value2</td>
      </tr>
    </table>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Related Articles