0

I have a two column layout as in this picture:

enter image description here

Each column contains rows composed of an icon and a label of text.

Each row of the left column must be aligned to the left, as is.

The rows of the right column must be aligned in such a way that the widest row is touching the right edge of the parent container and the other rows align so that their left edges are aligned, as in this picture:

enter image description here

It's hard to wrap my head around that... I am thinking of setting the container's display to flex, setting each column's flex to 1 so that they're of equal width, and then trying to do something with the rows of the right column, but I don't know what. I don't know in advance what the labels of text will be, but I'm sure it's possible they will greatly vary in length and can wrap. Is it even possible to align wrapping label to the right after it has wrapped?

Here's the code that I have so far https://jsfiddle.net/t7qksr3g/1/. It's based on @Kretiss answer, but it doesn't work correctly. When the text in the right column wraps, it doesn't align to the right.

I hope someone can help me. The solution can be completely different from what I've described above, it's not a requirement that the rows are actually inside of vertical containers, I just need to achieve the visual effect.

UPDATE

I think what I want to achieve might be impossible without using JS, because browser's logic for computing container's width with wrapped text inside doesn't work in a way that would allow it CSS Width / Max-Width on Line Wrap?.

Salivan
  • 1,876
  • 7
  • 26
  • 45
  • At least provide the an example of HTML structure, so people have something to work with (without having to create it themselves.) – CBroe Mar 02 '21 at 09:43
  • @CBroe I don't want to limit the solutions to the structure that I am thinking of, as I have no idea what the simplest or maybe the only possible solution could look like. – Salivan Mar 02 '21 at 09:45
  • 1
    _“Is it even possible to align wrapping label to the right after it has wrapped?”_ - tricky in general, see f.e. https://stackoverflow.com/q/41389292/1427878 – CBroe Mar 02 '21 at 09:45

1 Answers1

2

In the end, I found a solution. Since my original solution is already included in the question, I will edit this answer to the new one.

Here is working fiddle: https://jsfiddle.net/Kretiss/mbt68qw2/

First, here is the HTML. Add class editWidth to paragraphs which might be edited.

<div class="container">

    <div class="column">
      <div class="columnChild">
        <img src="smile.jpg">
        <p class="">Some text</p>
      </div>
      <div class="columnChild">
        <img src="smile.jpg">
        <p>Some text that wraps because its long long long</p>
      </div>
      <div class="columnChild">
        <img src="smile.jpg">
        <p>Some text</p>
      </div>
    </div>

    <div class="column">
        <div class="columnChild">
          <img src="smile.jpg">
          <p>Some longerrrrr text</p>
        </div>
        <div class="columnChild">
          <img src="smile.jpg">
          <p>Some text</p>
        </div>
        <div class="columnChild">
          <img src="smile.jpg">
          <p class="editWidth">Some text that wraps because its long sad Some text that wraps because its long</p>
        </div>
    </div>

  </div>

CSS is pretty much the same.

*{
  box-sizing: border-box;
}

.container{
  max-width: 500px;
  width: 100%;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  border: 2px solid black;
}

.column{
  width: fit-content;
  width: -moz-fit-content;
  width: -webkit-fit-content;
  border: 1px solid red;
}

.columnChild{
  display: flex;
  justify-content:flex-start;
  align-items: center;
}

.columnChild img{
  height: 50px;
}

And here is the magic. Include JQuery to file for example via this script <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> and then add this script:

<script>
$(document).ready(function(){

  $.fn.textWidth = function(){
    const html_org = $(this).html();
    const html_calc = '<span>' + html_org + '</span>';
    $(this).html(html_calc);
    const width = $(this).find('span:first').width();
    $(this).html(html_org);
    return width;
  };

  function changeWidth(resizing){
    const elements = $(".editWidth");

    elements.each(function(index){
      if(resizing) $(this).css("width", "auto");

      const currentWidth = $(this).textWidth();
      $(this).css("width", currentWidth + 2);

    });

  }

  changeWidth(false);

  $(window).resize(function(){
    changeWidth(true);
  });

});

</script>

All starts with changeWidth(false); after DOM is loaded. It calls the changeWidth(resizing) function with false argument, because browser windows is not resizing. This function loop through all paragraphs, which containts editWidth class. Inside .each() function is call to $.fn.textWidth function which returns exact width of text inside paragraphs. After that the line $(this).css("width", currentWidth + 2); set width of paragraph to width of text + 2px (you can change it if you want).

And when user resize browser, the

$(window).resize(function(){
  changeWidth(true);
});

gets called and do the same as described above. The only difference is that it first sets the width of the paragraph to auto, otherwise the width of the text could be different than it really should be.

Function which returns exact width of the text is from this post: Calculating text width

Kretiss
  • 657
  • 4
  • 15
  • Column cannot have static width, i.e. `max-width: 200px;`. It should be as wide as possible. That's where the complexity comes from. – Salivan Mar 02 '21 at 11:08
  • The text can wrap, etc. – Salivan Mar 02 '21 at 11:16
  • Yes, but how do you want to make the gap between them? – Kretiss Mar 02 '21 at 11:19
  • Maybe you can change css of column to this: `max-width: fit-content; max-width: -moz-fit-content; width: 40%;`, and with width define how wide it will be. – Kretiss Mar 02 '21 at 11:21
  • The gap is not necessary, column children can touch each other. The goal is to align the right column's widest child to the right and all the others based on that. Here, I've modified your code to not set static width for the column and included some text that wraps https://jsfiddle.net/t7qksr3g/. Now it doesn't align to the right correctly. – Salivan Mar 02 '21 at 11:27
  • I think it's impossible https://stackoverflow.com/questions/12377826/css-width-max-width-on-line-wrap/12377883#12377883, because browser's logic for setting container's width with wrapping text inside doesn't work like that. – Salivan Mar 02 '21 at 11:41
  • @Salivan I found a solution and adjusted the answer. – Kretiss Mar 02 '21 at 15:59