Search code examples
csshtml-tablewidthcolumn-width

Is it possible to make the first two columns of a table as wide as their content with the third column occupying the remaining space?


Still can't make a proper chatbox ;/

My requirements are simple: The first column goes for the timestamp, the second column goes for the poster's nick, the last column goes for the message content. Therefore: The first two columns should take as much space as necessary to avoid linebreaks, but no more to avoid wasting space; while the 3rd column should take the remaining space, but no more, forcing linebreaks if necessary.

However, both table layouts - auto and fixed - fail at this.

table-layout: auto; breaks lines in the first two columns and, if a single huge word is entered as the message content, stretches the table abnormally despite overflow-wrap: break-word:

.chatbox {
  display: table;
}

.message {
  display: table-row;
}

.timestamp, .author, .content {
  display: table-cell;
  padding-right: 10px;
}

.content {
  overflow-wrap: break-word;
}
<ul class="chatbox">
  <li class="message">
    <span class="timestamp">9.07.2019, 17:22:50</span>
    <span class="author">Some Longer Nick</span>
    <span class="content">I can see linebreaks in the preceeding two columns and I'd like to avoid them.</span>
  </li>
  <li class="message">
    <span class="timestamp">9.07.2019, 17:27:41</span>
    <span class="author">Nick</span>
    <span class="content">AnAbsurdlyLongWordThatCompletelyAndUtterlyDisruptsTheLayoutOfMyChatbox</span>
  </li>
</ul>

table-layout: fixed; does not allow me to set the first two columns to widths that depend on their content:

body {
  width: 500px;
}

.chatbox {
  display: table;
  table-layout: fixed;
  width: 100%;
}

.message {
  display: table-row;
}

.timestamp, .author, .content {
  display: table-cell;
  padding-right: 10px;
}

.content {
  overflow-wrap: break-word;
}
<ul class="chatbox">
  <li class="message">
    <span class="timestamp">9.07.2019, 17:22:50</span>
    <span class="author">Nick1</span>
    <span class="content">Too much blank space surrounding the timestamp and authors' nicks do not leave enough space for message contents</span>
  </li>
  <li class="message">
    <span class="timestamp">9.07.2019, 17:27:41</span>
    <span class="author">Nick2</span>
    <span class="content">To some extend I could remedy this by explicitely setting column widths, however, this would obviously not adapt to varying lengths of nicks. Only short nicks talking would again waste space while longer nicks could break</span>
  </li>
</ul>

Is it possible to do what I want using display: table?


Solution

  • Consider white-space: nowrap; with you first solution

    .chatbox {
      display: table;
    }
    
    .message {
      display: table-row;
    }
    
    .timestamp, .author, .content {
      display: table-cell;
      padding-right: 10px;
    }
    
    .timestamp, .author {
        white-space: nowrap;
    }
    .content {
      overflow-wrap: break-word;
      word-break:break-word;
    }
    <ul class="chatbox">
      <li class="message">
        <span class="timestamp">9.07.2019, 17:22:50</span>
        <span class="author">Some Longer Nick</span>
        <span class="content">I can see linebreaks in the preceeding two columns and I'd like to avoid them.</span>
      </li>
      <li class="message">
        <span class="timestamp">9.07.2019, 17:27:41</span>
        <span class="author">Nick</span>
        <span class="content">AnAbsurdlyLongWordThatCompletelyAndUtterlyDisruptsTheLayoutOfMyChatbox</span>
      </li>
    </ul>