2

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

这里有一些例子:http ://codepen.io/anon/pen/jiCxo

在此处输入图像描述

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

我想:

  • 2 就像 #3 一样,无需<br>手动添加。

  • 为“长”和短文本使用相同的 HTML 和 CSS。

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

有任何想法吗?

(如果我担心只使用 CSS 是不可能的,我愿意接受一个不错的 JavaScript 解决方案)

4

5 回答 5

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)
    }
  }
});

编辑:

要使第一行比第二行短,您必须做一些更复杂的事情。我从这个答案中使用了 cut 。这应该非常接近您想要的。

$(".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;
    };
}

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

编辑2:

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

于 2013-09-09T18:37:07.170 回答
1

我提出了一个解决方案,它利用了一个仍然相当未知的名为 MediaClass的 JS 库,它可以使用页面上特定元素的媒体查询。

我认为我设置值的方式看起来不错,但您可能希望通过更改 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类添加到h1ifh1的宽度在200pxand300px和一个large类 ifh1的宽度大于300px

CSS:

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

该位添加一个:before宽度取决于h1内部宽度的伪元素h1,在文本之前,这将第一行移动到内部h1,这会改变文本的流动。

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

于 2013-09-09T19:48:43.700 回答
0

I don't think you can do that with only CSS. Here's a Javscript snippet that you can try implementing to parse your strings. It's clunky and untested but allows you to have a preset both for the char length you want, as well as a word length. I'm sure you could clean it up and make it fit your needs.

// 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
});

Here's a link: http://codepen.io/jnickg/pen/szIpd

于 2013-09-09T18:51:47.783 回答
0

您需要 JavaScript 来执行此操作。CSS 不能根据一组复杂的规则来格式化文本。

于 2013-09-09T18:36:52.513 回答
0

TMP 的回答对另一个问题的回答的启发,我想出了这个脚本,它在大多数情况下都很好用,但仍然有一些怪癖……</p>

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);
    }

});

您可以在这里看到它的实际效果。不幸的是,我仍然不喜欢#8 和#13。欢迎提示和改进。

于 2013-09-10T12:36:56.763 回答