如何在不包装的情况下在HTML中显示字符串?

时间:2013-09-15 21:00:25

标签: html css dom

我正在为网站编写服务器端代码,我可以使用多个字符串来代表每个实体。例如:

[{
  full_name: 'San Francisco Giants',
  long_name: 'Giants',
  medium_name: 'Giants',
  short_name: 'SF'
}, {
  full_name: 'Arizona Diamondbacks',
  long_name: 'Diamondbacks',
  medium_name: 'D\'backs',
  short_name: 'AZ'
}, ...]

我想显示最长的字符串,它将适合我的固定宽度表而不包装。例如,在我想要的非常小的移动屏幕上:

/-------------\
| Team | Win %|
|------+------|
| SF   | .580 | 
| LA   | .510 |
| AZ   | .495 |
| CO   | .442 |
| SD   | .418 |
\______|______/

但是在略大的屏幕或肖像模式下,我想要

/--------------------------\
| Team       | Win %       |
|------------+-------------|
| "Giants"   | .580        | 
| "Dodgers"  | .510        |
| "D'backs"  | .495        |  <-- "Diamondbacks" (i.e., long_name) wouldnt fit
| "Rockies"  | .442        |       on one line, so the site displays "D'backs"
| "Padres"   | .418        |       (i.e. medium_name) instead.
\____________|_____________/

我没有使用固定宽度的字体。

这可以不借助Javascript来完成吗?

1 个答案:

答案 0 :(得分:2)

是的,它可以!

由于您无法提前知道哪个字符串适合,所以诀窍是将所有字符串放在DOM中,让浏览器的流规则确定哪个字符串适合。我将描述需要什么样的HTML和CSS,相应的服务器端代码应该变得清晰。

概述

假设您有一个div(“小工具”,如下所述),只有当其中的字符串无包装时才可见。然后,您可以通过以字符串长度的相反顺序垂直堆叠这些小工具来显示最长的字符串:

*-----------*
|  AZ       | \
*--\--------*
 \              \
     \
   \  *-----------*
      |  D'backs  | \
      *--\--------*
       \              \
           \
         \  *-----------*
            |           | \      <-- Empty because "Diamondbacks" doesn't fit.
            *--\--------*
             \              \
                 \
               \  *-----------*
                  |           |  <-- Empty because "Arizona Diamondbacks" doesn't
                  *-----------*      fit.

在页面上堆叠在一起,你只会看到第一个适合的字符串。例如,在上面的示例中,前两个小工具将不可见,您将看到

*-----------*
|  D'backs  |
*-----------*

因为AZ会被覆盖。

到目前为止我?大。但问题仍然存在:如何使div仅在其内部的字符串适合时才可见?换句话说,你怎么做...

小工具

这是一些真正的CSS魔术。你必须盯着它看几分钟才能思考它为什么会起作用。想象一个较小的“观察窗口”(div A),其后面有一个较大的div,宽度是其两倍(div B)。内部div B是间隔符(div C)和文本(div D)。整件事看起来像这样:

|-div B-----------------*------------------*
||-div C---------------||-div D---------|  | 
|| (hidden fixed-width ||\              |  | \
||     spacer div)     || D ' b a c k s |  |  
||_____________________|*__\____________|  *   \
|                                          |
|                        \   \             |     \
|                                          |
|                          \   \           |       \
|                                          |
|                            \   \         |         \ 
|                                          |
|______________________________\___\_______|           \

                                 \   \                   \

                                   \    *-div A-------------*
                                        |                   |
                                     \  |                   |
                                        *___________________*
隐藏了

div A溢出,所以当它全部垂直堆叠时,您只会看到div A后面发生的任何事情:在这种情况下,div D的内容:

  | div B -  -  -  -  -  -  *-div A-----------*
    | div C  -  -  -  -  -  |/-div D--------\ |  <-- Most of div B and all of div C
                            ||D ' b a c k s | |      are hidden because div A is
                            |\______________/ |      set to overflow hidden.
    |  -  -  -  -  -  -  -  |-----------------|



  | _  _  _  _  _  _  _  _  _  _  _  _  _  _  |

请注意,div Cdiv D都设置为在div B内浮动。如果div D内的字符串太长,它会在div C下方流动,而且它将不可见:

  | div B -  -  -  -  -  -  *-div A-----------*
    | div C  -  -  -  -  -  |                 |  <-- Most of div B and all of div C
                            |                 |      are hidden because div A is
                            |                 |      set to overflow hidden.
    |  -  -  -  -  -  -  -  |-----------------|
    /-div D--------------------\
    |  D i a m o n d b a c k s |
    \--------------------------/
  | _  _  _  _  _  _  _  _  _  _  _  _  _  _  |

这就是小工具!

以下是一些示例CSS,使其更加清晰:

.divA {
    position: relative;
    overflow: hidden;
}

.divB {
    position: absolute;
    top: 0;
    right: 0;
    width: 200%;
    height: 1000px /* arbitrarily large */
}

.divC {
    width: 50%;
    height: 50%;
    float: left;
}

.divD {
    float: left;
    background-color: white;
}

和DOM:

<div class="divA">
  <div class="divB">
    <div class="divC"></div>
    <div class="divD">AZ</div>
  </div>
  <div class="divB">
    <div class="divC"></div>
    <div class="divD">D'backs</div>
  </div>
  <div class="divB">
    <div class="divC"></div>
    <div class="divD">Diamondbacks</div>
  </div>
</div>

完整解决方案

以下是此处给出的整个示例的工作示例:http://jsfiddle.net/sFjdL/

(请注意,有一些微小的修改可以使高度自然流动,我在这里没有描述。)

ARrrgh。它必须如此复杂吗?为什么我不能......

近似每个字符的宽度为N像素?

你可以 - 但为了安全起见,你必须高估你需要的空间,所以它可能不是最佳的。为N选择最小的“安全”值很难,而且总是浪费。此外,您将无法为视力不佳的用户处理大字体。上述解决方案可以很好地扩展。

使用@media CSS为正确的外形选择正确的字符串?

同样,您必须提前知道每个字符串的长度是多少,这在服务器端是不可能的。你可能会接近,但为什么当你完美时“接近”?

分叉这个想法

您可以采用这个概念的方向很多。例如,这里的div只有当其中的字符串具有CSS省略号时才会悬停文本,因为它不适合:

.under {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 50%;
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
}

.over {
    position: relative;
    z-index: 2;
}

DOM:

<div class="divA">
    <div class="invisible_for_height"></div>
    <div class="divB">
        <div class="under" title="Expectorating">Expectorating</div>
        <div class="divC"></div>
        <div class="divD over">Expectorating</div>
    </div>
</div>

和演示:

http://jsfiddle.net/X3bqx/

另外,尝试将div设置为全部具有背景颜色并删除隐藏的溢出。它有助于调试!示例:http://jsfiddle.net/X3bqx/1/