How to center right-aligned numbers in table column using CSS?

前端 未结 11 2100
傲寒
傲寒 2021-02-02 10:54

The picture below illustrates what I\'m trying to accomplish:

\"enter

UPD. As you

相关标签:
11条回答
  • 2021-02-02 11:19

    Ok I encountered this problem yesterday , went through all the solutions and came up with my own solution that does not modify the DOM in a significant manner but uses JS but I will list the drawbacks of some of the solutions above

    1. Padding extra characters works if your font is monospace
    2. Creating a fixed padding or fixed width may affect responsive behavior
    3. Adding a second table inside column is serious DOM manipulation, if you have a 1000 rows and 30 columns, you will start seeing the effects of performance with such a heavy tree

    HTML (Using Bootstrap 4.1.1)

    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>#</th>
          <th>Symbol</th>
          <th>Price</th>
          <th>Volume</th>
          <th>Market Cap</th>
          <th>Circulating Supply</th>
          <th>Total Supply</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
    

    CSS

    .numeric{
      text-align: right;
    }
    
    
    #datatable th, #datatable td{
      text-align: center;
    }
    
    .centerspan{
      display: inline-block;
      text-align: right;
      background: yellow;
    }
    
    .root-rank, .root-price, .root-market_cap, .root-max_supply{
      background: #efefef;
    }
    

    JavaScript

    var overview_data = [
        { "rank": 1, "symbol": "BTC", "price": 8004.8, "volume_24h": 5864600000000.0, "market_cap": 137422500058.0, "circulating_supply": 17167512.0, "max_supply": 21000000.0},
        { "rank": 2, "symbol": "ETH", "price": 471.305, "volume_24h": 1930260000.0, "market_cap": 47547607782.0, "circulating_supply": 100885006.0, "max_supply": null},
        { "rank": 3, "symbol": "XRP", "price": 0.454852, "volume_24h": 234947000.0, "market_cap": 17882817260.0, "circulating_supply": 39315683476.0, "max_supply": 100000000000.0},
        { "rank": 4, "symbol": "Bitcoin Cash", "price": 845.04, "volume_24h": 730498000.0, "market_cap": 14580563109.0, "circulating_supply": 17254288.0, "max_supply": 21000000.0},
        { "rank": 5, "symbol": "EOS", "price": 8.14097, "volume_24h": 691908000.0, "market_cap": 7295526131.0, "circulating_supply": 896149492.0, "max_supply": 1000000000.0} 
    ]
    
    
    var table = document.getElementById("datatable")
    var thead = table.tHead
    var tbody = table.tBodies[0]
    var colClasses = []
    
    
    for(var i = 0, len= overview_data.length; i < len; i++){
      var tr = document.createElement("tr")
      for(var j in overview_data[i]){
        var td = document.createElement("td")
        td.classList.add("root-" + j)
        var span = document.createElement("span")
        span.classList.add("centerspan")
        span.classList.add('col-' + j)
    
        //Add this column classes to keep track of one class per column
        if (!colClasses.includes("col-" + j)){
           colClasses.push('col-' + j)
        }
        var text = document.createTextNode(overview_data[i][j] || -1)
        if(!isNaN(overview_data[i][j])){
          td.classList.add("numeric")
        }
        span.appendChild(text)
    
        td.appendChild(span)
        tr.appendChild(td)
      }
      tbody.appendChild(tr)
    }
    
    //This is the main part
    for(var i = 0; i < colClasses.length; i++){
      var items = document.querySelectorAll("." + colClasses[i])
      var max = 0
    
      //Loop through all the items in the col class
      for(var j = 0; j < items.length; j++){
        //Calculate max width of span containing text inside column
        if(items[j].offsetWidth > max){
           max = items[j].offsetWidth
        }
      }
    
      //Set width of each span to the max width
      for(var j = 0; j < items.length; j++){
        console.log(max)
        items[j].style.width = max + "px"
      }
    }
    

    Snapshot

    0 讨论(0)
  • 2021-02-02 11:19

    I believe the actual td in that table (if it is indeed a table) will have a fixed width, and lots of padding to give the illusion that it's centre-right-aligned.

    You could try a crude style such as this:

    /* For demonstration purposes, a fixed width `th`. */
    th.headrowrnum {
        width: 200px;
    }
    
    td.rightalignnum {
        width: 100px;
        padding: 0 50px;
        text-align: right;
    }
    

    HTML:

    <table>
        <tr>
            <th>Col 1</th>
            <th class="headrowrnum">Col 2</th>
        </tr>
        <tr>
            <td>X</td>
            <td class="rightalignnum">5</td>
        </tr>>
        <tr>
            <td>Y</td>
            <td class="rightalignnum">500</td>
        </tr>
    </table>
    
    0 讨论(0)
  • 2021-02-02 11:20

    There doesn’t seem to be any direct CSS method. But you could consider the approach suggested by @CMKanode in a comment. You would need to preprocess the numbers in the column and compute the largest of them (this requires locale-sensitive parsing since you are using a thousands separator), and then you would left-pad the numbers to the same number of characters, using U+2007 FIGURE SPACE as a space that has the same width as digits. And, of course, the column would be declared as centered.

    So in the example, “5” would be padded to &#x2007;&nbsp;&#x2007;&#x2007;&#x2007;&nbsp;&#x2007;&#x2007;5 (assuming you use a normal space as thousands separator; U+2009 THIN SPACE might be better, but it has font issues.

    The approach would mean that you need to use a font where digits have the same width (most fonts in computers do) and that contains U+2007.

    If the thousands separator were a comma or a period, for example, you would need to use U+2008 PUNCTUATION SPACE in its stead.

    In the end, I think this would be excessively complicated. It is probably better to make the column right-aligned but with a suitable left and right padding, selected as a good guess based on the width of the column header and the expected widths of the numbers.

    0 讨论(0)
  • 2021-02-02 11:25

    You can approximate this with CSS. Create a class:

    td.rt-ctr {
      text-align:right;
      padding-right:33%;    
    }
    

    Then call the class in your chart:

    <table>
      <tbody>
       <tr>
        <td>Item 1</td>
        <td class="rt-ctr">100.25</td>
       </tr>
       <tr>
        <td>Item 2</td>
        <td class="rt-ctr">99.75</td>
       </tr>
      </tbody>
    </table>
    

    Depending upon the width of the column, chart and longest data entry, you may need to adjust the percentage in the CSS. This approach isn't perfect, but it is responsive and is a pure CSS method.

    0 讨论(0)
  • 2021-02-02 11:25

    To achieve that alignment, you should do something like this:

    HTML:

    <td class="my_td">
        <div class="content">
            12345
        </div>
    </td>
    

    CSS:

    .my_td 
    {
        width: 200px;
        align: center;
    }
    
    .content
    {
        width: 100px;
        margin-left: auto;
        margin-right: auto;
        text-align: right;
    }
    

    You just need to adapt the widths to meet your requirements, for instance, max digits in the number.

    0 讨论(0)
  • 2021-02-02 11:29

    Add a div to td:

    <td>
        <div align="center">
            <p style="text-align:right">Text Aligned Right</p>
        </div>
    </td>
    

    Then add padding / margins to fine tune the placement of the div.

    0 讨论(0)
提交回复
热议问题