3

私は Web サイトのサーバー側コードを書いており、各エンティティを表す複数の文字列を自由に使用できます。例えば:

[{
  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に頼らずにこれを行うことはできますか?

4

1 に答える 1

3

はい、できます!

どの文字列が適合するかを前もって知ることはできないため、すべての文字列を DOM に配置し、ブラウザーのフロー ルールによってどの文字列が適合するかを判断するようにします。どのような HTML と CSS が必要かを説明すると、対応するサーバー側のコードが明らかになるはずです。

概要

内部の文字列が折り返されずに収まる場合にのみ表示されるdiv(後述の「ガジェット」) があるとします。次に、これらのガジェットを文字列の長さの逆順に垂直に積み重ねることで、収まる最長の文字列を表示できます。

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

ページ上で互いに積み上げられているため、最初に収まる文字列のみが表示されます。たとえば、上の例では、最初の 2 つのガジェットが非表示になり、

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

AZカバーされるからです。

ここまで私と?偉大な。divしかし、問題は残ります:内部の文字列が収まる場合にのみ表示される をどのように作成しますか? つまり、どうやって作る...

ガジェット

これが実際の CSS マジックです。なぜ機能するのかを考えるために、数分間じっと見つめる必要があります。小さい「表示ウィンドウ」( div A) のすぐ後ろに、2 倍の幅 ( div B) の大きな div が配置されていると想像してください。内部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/

(ここでは説明しませんが、高さが自然に流れるようにいくつかの小さな変更があることに注意してください。)

うーん。それほど複雑にする必要がありますか?なぜできないの...

各文字がNピクセル幅であることを概算しますか?

できますが、念のために必要なスペースを過大評価する必要があるため、最適ではない可能性があります。の最小の「安全な」値を選択するのNは難しく、常に無駄になります。さらに、視覚障害のあるユーザーのために大きなフォント サイズを処理することはできません。上記のソリューションは問題なくスケーリングします。

CSS を使用@mediaして、適切なフォーム ファクタに適切な文字列を選択しますか?

繰り返しますが、各文字列の長さが何ピクセルかを事前に知る必要がありますが、これはサーバー側では不可能です。おそらく近づくことはできますが、完璧にできるのになぜ「近づく」のでしょうか?

このアイデアをフォークする

この概念を採用する方向はいくつかあります。たとえば、次の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/

また、divs をすべて背景色に設定し、オーバーフローを非表示にします。デバッグに役立ちます!例: http://jsfiddle.net/X3bqx/1/

于 2013-09-15T21:00:25.167 に答える