5

Consider this example:

CSS

.a1 {
      border-style: solid;
      border-width: 1px;
      font-size: 1em;
      line-height: 1.25em;
      height: 2.5em;
      max-height: 2.5em;
    }
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>

<body>
  <h1>Hello World!</h1>

  <div class="a1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad </div>

</body>
</html>

Currently, it behaves in Firefox 43 like this upon resizing page width:

ffox-scale.gif

That is, the text attempts to fill the width of the div (which is set by width of the page).

What I want to do instead, is to:

  • Fix the height to two text lines (or as I did, 2.5em, if line-height is 1.25 em, and font-size 1em);
  • (Assuming the text is a single line) - fix the width, so the text fits in two text lines, and the width of the first line is approximately the same as the width of the second line

... that is, I would like the div to be formatted like this:

ffox-two-lines-ok

... and it would remain like this - have a fixed width/height - upon browser window scaling. And specifically - I do not want to set an explicit width for the div, but the div width should be set based on text contents:

  • if the text contents' width is smaller than say 200 px (i.e. a single line is assumed), then the div width is 200 px
  • if the text contents' width is greater than 200 px, two lines are assumed, so the text is broken up so there are approx same contents in both lines, and then the width of the longer line is takes

Is this possible to do with pure CSS - and if not, is there an approach someone could suggest with JS (or jQuery) + CSS?

Yaseen Ahmad
  • 1,807
  • 5
  • 25
  • 43
sdbbs
  • 4,270
  • 5
  • 32
  • 87
  • 1
    Sorry, I don't quite understand what you need but still wanna give it a try. Do you mean something like this? https://jsfiddle.net/ymepkmh7/ – Michael Eugene Yuen Apr 28 '16 at 13:33
  • 2
    @MichaelEugeneYuen No, OP wants the div to stay at a certain min-width so that the complete content is visible (in two lines at most). – Paul Apr 28 '16 at 13:44
  • Thanks @MichaelEugeneYuen - indeed Paul is right; in your case, if the width of browser is small enough, I get three lines ( http://i.stack.imgur.com/2VL5t.png ); what I want is that it remains at two. – sdbbs Apr 28 '16 at 13:47

2 Answers2

2

ok, The easiest way to do so is to fix the width of the div you could also add text-align: justify. you could see it in this plunker

text-align: justify;
text-justify: inter-word;
width: 30em;

although it is not really worth it. The text-align and text-justify have no use here I just added them so that you know they exist.

but if you want to go through the hard path of calculating the width of your text and setting the div to half that width. you could find alot of help here

Community
  • 1
  • 1
Mostafa Fateen
  • 849
  • 1
  • 14
  • 33
  • Thanks for that @MostafaFateen - however, your solution also leaks a third line outside the box, so I cannot use it; thanks for the link, I had seen it before - and I was lloking for it, but couldn't find it; I ended up rolling my own "hard path" solution with width/height calculations, posted it below as an answer. Cheers! – sdbbs Apr 28 '16 at 14:28
1

Well, apparently a plain CSS solution isn't possible; and I remember seeing elsewhere on this site a JS solution that does text breaking, but I couldn't apply it to my problem at the time, so I forgot the reference - so now I rolled my own, which at least has plenty of console.log throughout.

So, here is my solution, that does exactly what I wanted:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script type="text/javascript" src="/media/Data1/work/bbs/gits/econdk-vis-01_git/jquery-1.12.3.min.js"></script>
  <style type="text/css">
.a1 {
  border-style: solid;
  border-width: 1px;
  font-size: 1em;
  line-height: 1.25em;
  height: 2.5em;
  max-height: 2.5em;
}
  </style>
  <script type="text/javascript">
  // see SO: 1582534
$.fn.getWidthSingleLine = function(){
  var contents = this.contents(),
      wrapper  = '<span style="display: inline-block; white-space: nowrap;" />',
      width    = '';
  contents.wrapAll(wrapper);
  //contents.parent().css("white-space", "nowrap"); // try this, instead of setting unreasonable large width? ok - though set explicitly above
  var fontsize = parseFloat( contents.parent().css("font-size") ); //px
  width = contents.parent().width(); // parent is now the wrapper
  contents.unwrap();
  return {
    widthpx: width,
    widthem: width / fontsize
  };
}
$.fn.getHeightFromWidth = function(inwidth){
  var contents = this.contents(),
      wrapper  = '<span style="display: inline-block;" />',
      width    = '';
  contents.wrapAll(wrapper);
  contents.parent().width(inwidth); // parent is now the wrapper
  var fontsize = parseFloat( contents.parent().css("font-size") ); //px
  height = contents.parent().height(); // parent is now the wrapper
  contents.unwrap();
  return {
    heightpx: height,
    heightem: height / fontsize
  };
};

ondocready = function() {
  var retwobj = $("#txtest").getWidthSingleLine();
  console.log( retwobj.widthem + " em " + retwobj.widthpx + " px ; docw " + $(document).width() + " winw " + $(window).width() );
  var findwidthpx = retwobj.widthpx/2;
  var rethobj = $("#txtest").getHeightFromWidth( findwidthpx );
  // note: $("#txtest").css("max-height")) is in pixels!
  var maxh = parseFloat( $("#txtest").css("max-height") );
  var hdiffpx = rethobj.heightpx - maxh;
  console.log( rethobj.heightem + " em " + rethobj.heightpx + " px ; hdiffpx: " + hdiffpx + " ; findwidthpx: " + findwidthpx);
  // if we take the width of single line and halve it, we will
  // get at least two lines, maybe more - but certainly not less than two lines
  // ergo, hdiffpix should always be >= 0
  while (hdiffpx > 0) {
    // increase slowly findwidthpx; say steps of 10 px
    findwidthpx += 10;
    rethobj = $("#txtest").getHeightFromWidth( findwidthpx );
    hdiffpx = rethobj.heightpx - maxh;
    console.log(" in loop: ", rethobj.heightem + " em " + rethobj.heightpx + " px ; hdiffpx: " + hdiffpx + " ; findwidthpx: " + findwidthpx);
  }
  console.log(" after loop: ", rethobj.heightem + " em " + rethobj.heightpx + " px ; hdiffpx: " + hdiffpx + " ; findwidthpx: " + findwidthpx);
  // assign finally
  $("#txtest").width(findwidthpx);
}
$(document).ready(ondocready);
  </script>
</head>

<body>
  <h1>Hello World!</h1>

  <div id="txtest" class="a1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad </div>

</body>
</html>

... and its expected console.log output is like this:

68.375 em 1094 px ; docw 1386 winw 1386                   
3.75 em 60 px ; hdiffpx: 20 ; findwidthpx: 547            
 in loop:  3.75 em 60 px ; hdiffpx: 20 ; findwidthpx: 557 
 in loop:  3.75 em 60 px ; hdiffpx: 20 ; findwidthpx: 567 
 in loop:  3.75 em 60 px ; hdiffpx: 20 ; findwidthpx: 577 
 in loop:  2.5 em 40 px ; hdiffpx: 0 ; findwidthpx: 587   
after loop:  2.5 em 40 px ; hdiffpx: 0 ; findwidthpx: 587

If a better answer comes along, I'll re-accept it....

sdbbs
  • 4,270
  • 5
  • 32
  • 87