首选新行到长行

时间:2013-09-09 17:53:19

标签: javascript css

我想控制文本在框中的显示方式,更喜欢新行到长行,但仍允许长行。

以下是一些示例:http://codepen.io/anon/pen/jiCxo

enter image description here

  • 在#1中,有一个“长”文本和长行。这就是我希望它表现的方式。
  • 在#2中,有一个短文本和一个长行。我不喜欢它。

我想:

  • 2与#3类似,无需手动添加<br>

  • 使用相同的HTML&amp; “长”和短文的CSS。

另外,我希望第一行是最短的,而不是最后一行:http://codepen.io/anon/pen/irFcK

有什么想法吗?

(如果,我担心,仅使用CSS是不可能的,我会接受一个很好的JavaScript解决方案)

5 个答案:

答案 0 :(得分:1)

我做了一个快速的功能,应该做你想要的。我评论了它,所以你知道发生了什么。

$(".box h1").each(function() {
  // Check if one line
  if($(this).height() <= parseInt($(this).css('line-height'))){
    // Check if width is greater than %50 of parent
    if($(this).width() >= $(this).parent().width()/2){
      // Adjust width to put it on two lines
      $(this).width($(this).parent().width()/2)
    }
  }
});

编辑:

要使第一行比第二行短,你必须做一些更复杂的事情。我使用来自this answer的剪辑。这应该非常接近你想要的。

$(".box h1").each(function() {
  // Check if one line
  if($(this).height() <= parseInt($(this).css('line-height'))){
    // Check if width is greater than %50 of parent
    if($(this).width() >= $(this).parent().width()/2){
      // First find approximately where you want it
      place = Math.round($(this).val().length/2);         // Might need a parseFloat
      // Find nearest end of word in correct direction
      original = $(this);
      first = original.text(cut(place));

      end = first.val().length
      start = $(this).val().length - end
      second = $(this).substr(start,end)

      // Place a break tag in the middle to put it on two lines
      $(this).html(first + <br> + second)
    }
  }
});

这是剪切

function cut(n) {
    return function textCutter(i, text) {
        var short = text.substr(0, n);
        if (/^\S/.test(text.substr(n)))
            return short.replace(/\s+\S*$/, "");
        return short;
    };
}

此代码使用<br>分隔两行(第二行更长)

EDIT2:

如果没有<br>或其他添加新行的方式,则行长度不可能不同。如果您更喜欢它我可以更改它,因此它使用多个<h1>标记,我认为这会自动将每个添加标记添加到新行

答案 1 :(得分:1)

我提出了一个使用still fairly unknown JS library named MediaClass的解决方案,该解决方案可以使用页面上特定元素的媒体查询。

我认为我设置值的方式看起来很不错,但你可能想通过改变JS或CSS中的宽度来微调它。这是一个 jsFiddle ,因为你的修补乐趣。

它的工作方式:

JS:

MediaClass("large", "h1:media(this-min-width: 300px)");
MediaClass("small", "h1:media(this-min-width: 200px and this-max-width: 300px)");

如果small的宽度介于h1h1以及200px之间,这些行可确保将300px类添加到large如果h1宽于300px,则为class。

CSS:

.large:before {
    content:"\A"; 
    width: 50%;
    display: inline-block;
}
.small:before {
    content:"\A"; 
    width: 30%;
    display: inline-block;
}

此位在文本之前添加:before宽度的h1伪元素,具体取决于h1h1的宽度,这会移动{{1}内的第一行1}} over,它改变了文本的流程。

编辑:我修改了帖子和小提琴,以更好地演示此解决方案如何回答所提出的问题。

答案 2 :(得分:0)

你需要JavaScript才能做到这一点。 CSS无法根据一组复杂的规则格式化文本。

答案 3 :(得分:0)

我认为只有CSS才能做到这一点。这是一个Javscript片段,您可以尝试实现它来解析您的字符串。它很笨拙且未经测试,但允许您为所需的字符长度以及字长设置预设。我相信你可以清理它并使它符合你的需要。

// requires h1 field to have line-height property set
$(".box h1").each(function()
{
  // splits if over this % width
  var preset = 50;
  // indents first line to same as preset percentage
  // to attempt to make first line shorter
  var indent = String(preset) + 'px';
  // height of a standard line
  var lh = parseInt($(this).css('line-height'));
  // width of the box
  var w = $(this).parent().width() * (preset/100);

  // if the text field is one line heigh & over the preset
  if(($(this).height() <= lh) && ($(this).width() >= w))
  {
    $(this).width(w);
    $(this).css('text-indent' , indent);
  }
  // otherwise it's fine
});

这是一个链接:http://codepen.io/jnickg/pen/szIpd

答案 4 :(得分:0)

受到TMP's answerthis answer的启发,我想到了这个在大多数情况下效果很好但仍有一些怪癖的脚本......

var minimum_gap = 5; // Minimum gap on the last line to try to put it on the first.

$(".box h1").each(function() {
    var h1 = $(this),
        text = h1.text(),
        words = text.split(' '),
        lines = [],
        first_word = [],
        l = 0,
        i = 0;

    // Adding a span to measure the width
    h1.wrapInner('<span>');
    var span = h1.find('span');

    // Put the first word in the span and save the height
    span.text(words[0]);
    var height = h1.height();

    // Measure width of each line
    for(var i = 1; i < words.length; i++){
        span.append(' ' + words[i]);

        // If there's a new line
        if(h1.height() > height){
            lines[l] = span.width();
            span.text(words[i]);
            l++;
        }
    }
    // Last line
    lines[l] = span.width();

    var nb_lines = lines.length;
        ideal_line_width = 0;

    if(nb_lines == 1) {
        // If the line is "long", make it two
        if(span.width() >= h1.parent().width()/2) {
            ideal_line_width = h1.width()/2;
            nb_lines = 2;
        }
    }
    else {
        // Compute the average lines width (except for the last one)
        var sum = 0;
        for(l=0;l<(nb_lines-1);l++) {
            sum += lines[l];
        }
        var avg_width = sum/(nb_lines-1);

        // If last line is shorter than the average
        if(lines[nb_lines-1] < avg_width) {
            var gap = avg_width - lines[nb_lines-1];

            // Spread the gap among the lines
            gap /= nb_lines;

            if(gap > minimum_gap) {
                ideal_line_width = avg_width - gap;
            }
        }
    }

    // Let's make the wanted adjustments
    if(ideal_line_width != 0) {

        // Determining which is the first word of each line, beginning at the end in order to get the shortest one first
        l = nb_lines-1;
        span.empty();
        for(i=words.length-1;i>=0;i--) {
            span.prepend(words[i] + ' ');
            if(span.width() > ideal_line_width) {
                // If there's a new line, we cancel the last word
                if(h1.height() > height) {
                    i++;
                }
                span.empty();
                first_word[l] = i;
                l--;
            }
        }

        // Applying the results
        span.remove();
        l = 1;
        for(i=0;i<words.length;i++) {
            h1.append(' ' + words[i]);
            if(first_word[l] == i+1) {
                h1.append('<br>');
                l++;
            }
        }

    }
    // Or just display the text
    else {
        span.remove();
        h1.text(text);
    }

});

你可以see it in action here。不幸的是,我仍然不喜欢#8和#13。欢迎提示和改进。