steak2002
steak2002

Reputation: 177

How to make parent element shrink when line breaks?

How can I a make a HTML parent element adjust its width, when a child element text wraps to a new line? Do I need to use javascript or can it be done with css?

Below is an example.

ul {
  align-items: stretch;
  justify-content: center;
  background: lightgrey;
  display: flex;
  flex-direction: row;
  height: 80px;
  justify-content: flex-start;
  padding-top: 20px;
  padding-bottom: 20px;
}
li {
  background-color: #303E49;
  display: flex;
  list-style: none;
  margin-right: 0.5em;
}
a {
  color: white;
  text-decoration: none;
  margin: 0.5em 0.5em 0.5em 0.5em;
  border: 1px solid white;
}
Resize this window horizontally to see what I am talking about.

<ul>
  <li>
    <a href="#">HowCanIMakeThisBoxShrink
            WhenTheTextBreaksToANewLine?</a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
</ul>

I need the container element <li></li> width to match the text width of its child <a></a>. In my current implementation the width of <a></a> is decreased, when the text breaks to a new line, but not the width of the <li></li>

Thanks

Upvotes: 8

Views: 1350

Answers (3)

Kai
Kai

Reputation: 44

You could

  • add an overflow-wrap in combination with fit-content for the links (not sure if you want all a-elements to work the same way, then just get rid of the additional break-class)
  • remove the 80px fixed-height from the ul element (not sure if your app plans accept a flexible height. I had to remove the fixed value to make the element expand properly in vertical direction

Let me know if this approach is helpful:

ul {
  align-items: stretch;
  justify-content: center;
  background: lightgrey;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  padding-top: 20px;
  padding-bottom: 20px;
}

li {
  background-color: #303E49;
  display: flex;
  list-style: none;
  margin-right: 0.5em;
}

a {
  color: white;
  text-decoration: none;
  margin: 0.5em 0.5em 0.5em 0.5em;
  border: 1px solid white;
}

a.break {
  overflow-wrap: anywhere;
  height: fit-content;
}
Resize this window horizontally to see what I am talking about.

<ul>
  <li>
    <a class="break" href="#">HowCanIMakeThisBoxShrink
            WhenTheTextBreaksToANewLine?</a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
</ul>

Upvotes: 1

dweller
dweller

Reputation: 36

I just tried to replace newlines with <br> on resize (when the span height changes). It works when resizing down. Now maybe adding the replacement of <br> to newline on resizing up (maybe remember the width at which was the replacement done).

var before=$("#shrink a span").height();

$( window ).resize(function() {
  //alert(replaced);
  var elem = $("#shrink a span");
  var now = elem.height();
  var str=elem.html();
  if (now > before) {
    elem.html(str.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2'));
  } 
  //$( "body" ).prepend( "<div>"+before+' '+now+"/div>" );
  before = elem.height(); 
});
ul {
  align-items: stretch;
  justify-content: center;
  background: lightgrey;
  display: flex;
  flex-direction: row;
  height: 80px;
  justify-content: flex-start;
  padding-top: 20px;
  padding-bottom: 20px;
}
li {
  background-color: #303E49;
  display: flex;
  list-style: none;
  margin-right: 0.5em;
}
a {
  color: white;
  text-decoration: none;
  margin: 0.5em 0.5em 0.5em 0.5em;
  border: 1px solid white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Resize this window horizontally to see what I am talking about.

<ul>
  <li id="shrink">
    <a href="#"><span>HowCanIMakeThisBoxShrink
            WhenTheTextBreaksToANewLine?</span></a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
  <li>
    <a href="#">Text</a>
  </li>
</ul>

Upvotes: 0

John
John

Reputation: 312

Currently, you only have the content forcing those divs open. If you define the widths of those divs, you should get the desired effect you're looking for. Something like this would create an even three-column layout:

li{
   width: 33.33%;
}

However, it sounds like you want something a little more dynamic than a static three-column layout, but I'm not exactly sure what you are looking for. If my solution above doesn't help, can you perhaps explain what you're looking for in greater detail?

Upvotes: 0

Related Questions