2017-03-13 6 views
1

次のHTML(JSFiddle here)では、「このテキストを折り返すのはなぜですか」のテキストは、幅が狭すぎてテキストの一部が切り取られてしまった場合にのみ折り返します。その後、それはラップします。このスパンを正しくラップできないのはなぜですか?

私が必要とする動作は、テキストを1つの項目として折り返して、ワード単位で折り返しを開始するためのテキストではないことに注意してください。実際にはうまくいくことに注意してください。しかし、一度幅が小さくて先の画像なしで折り返された場合にのみ機能します。先頭のイメージを削除すると、正常に動作します。

先の画像を適切な位置に配置して、希望のラッピング動作を得る方法はありますか?

#main-toolbar { 
 
    height: 140px; 
 
    white-space: nowrap; 
 
    overflow:hidden; 
 
    width: 100%; 
 

 
} 
 

 
#main-toolbar-text{ 
 
    height: initial; 
 
    display:inline-block; 
 
    color: #2196f3; 
 
    line-height: 70px; 
 
} 
 

 
.test{ 
 
    border: solid red 1px; 
 
} 
 
.profile-toolbar-user-wordmark{ 
 
    display: inline-block; 
 
    white-space: normal; 
 
    overflow: initial; 
 

 
} 
 

 
.profile-toolbar-wordmark{ 
 
    width: 90px; 
 
} 
 

 
.profile-toolbar-logoicon{ 
 
    width: 90px; 
 
} 
 

 
.profile-toolbar-icon{ 
 
    display: inline-block; 
 
    vertical-align: top; 
 
    overflow: visible; 
 
    white-space: nowrap; 
 
}
<div id="main-toolbar" class="test" > 
 
    
 
    <span class="profile-toolbar-icon test"><img class="profile-toolbar-logoicon" src="https://pixy.org/images/placeholder.png"></span> 
 
    <span class="profile-toolbar-user-wordmark test"> 
 
     <span class="profile-toolbar-icon"> 
 
      <img class="profile-toolbar-wordmark" src="https://pixy.org/images/placeholder.png"> 
 
     </span> 
 
     <span id="main-toolbar-text"> 
 
      Why won't this text wrap? 
 
     </span> 
 
    </span>  
 
</div>

+0

良い質問。私はその原因や解決策はわかりませんが、回避策があります:テキストブロック(メインツールバーテキスト)に適切なパディングを与えて、そのコンテナが実際よりも広いと考えるようにし、早くラップします。 94pxで十分です。最初のアイコンの幅+中間のスペースの幅。 https://jsfiddle.net/MrLister/3L3pq5L5/5/ –

+0

'white-space:nowrap;を削除すると、期待通りに折り返されます。 – Stickers

+0

@Panglossこれは 'profile-toolbar-user-wordmark'クラスの要素が 'profile-toolbar-icon'要素の下にくるようにします。私はそれを包むものではありません。私はテキストを 'profile-toolbar-user-wordmark'要素内のイメージの下に折り返して、その要素自身をラップしないでください。 – WillyC

答えて

1

ここで最も簡単な解決策はdisplay: flexを使用することです。ここにはguide to flexboxがあります。フレックスの使用方法は、ブロックやインライン表示とは異なるビルトインビヘイビアが多く含まれているため、使用する前にどのように動作するのかを理解する必要があります。あなたが任意の幅を設定しなかったので

(または分/:あなたはフレックスおよび/またはあなただけのこの問題は、とにかく起こっている理由を知りたいされている使用したくない場合は

、読書を保ちます最大幅)を使用しており、ブロックの幅は暗黙的に100%です。display: inline-blockを使用しています。先頭の画像は90ピクセル幅なので、テキストを含むブロックは90ピクセル右にオフセットされます。

本質的に、先頭の画像+テキストを含むブロックが占める幅は実際には100%+ 90pxに等しいので、テキストを含むブロックをラップする前に余分な90pxのスペースがあるとブラウザは考えます。実際には、外側のdivの100%の幅を超えているため、余分な90ピクセルがクリップされてしまいます。このため、ラッピングは、幅が先行画像なしで折り返されるほど十分に小さい場合にのみ機能します。

ですから、この場合には90PXある先頭画像の余分な幅を減算するmax-widthを設定することができ、(フレックスなし)これを修正するには:

.profile-toolbar-user-wordmark { 
    display: inline-block; 
    white-space: normal; 
    overflow: initial; 
    max-width: calc(100% - 90px); /* 90px in this case, in general it should be whatever the width of the leading image is */ 
} 

一つ微妙警告:がある場合に応じて、境界線/マージン/パディングを使用する場合は、それを考慮に入れて減算幅を調整する必要があります。私。先頭の画像の余白が8ピクセルの場合は、max-widthcalc(100% - 98px)に設定する必要があります。また、先頭の画像の余白が8px、余白が8pxの場合、max-widthcalc(100% - 106px)である必要があります。左/右の枠線、余白、パディングはすべてこれに影響します。

以上により、あなたはあなたのケースでcalc(100% - 90px)からmax-width設定して、テキストをラップするために開始する前にサイズを変更するとき起こるクリッピングのほんの少し(数ピクセル分に相当)がまだあることに気づくことがあります。これは、適用した赤い枠線のために2px(左側に1px、右側に1px)、先頭の画像とテキストを含むブロック(コード内の改行によって2つのスパン)。残念ながら、スペース文字の幅は、ブラウザーやフォントサイズによって異なるため、どのような幅の文字が使用されているかを知る良い方法はありません。したがって、ピクセルの完成度に合わせてラッピングを修正するには、max-widthcalc(100% - 92px)に設定し、スペースを削除する必要があります(remove spaces between inline block elementsにはいくつかの方法があります)。要素間に空白領域が残っている場合は、マージンを設定することができます(max-widthの計算でそのマージンを考慮してください)。

最後に、上記のフレックスやハードコードされたCSSを使用していない場合は、JQueryを使用してCSSを動的に設定することができます(つまり、先頭のイメージ要素の幅をハードコードできない場合、あなたは本当にそのスペースを取り除きたいと思わない):

<span id="your-id" class="profile-toolbar-user-wordmark test">...</span> 

let $yourElement = $("#your-id"); 
let offsetLeft = $yourElement.offset().left - $yourElement.parent().offset().left; 
$yourElement.css("max-width", `calc(100% - ${offsetLeft}px)`); 
+1

私はこの提案された解決策がどのように機能するかについてのファンではありませんが(一般的には何も問題ありません)、この回答は私には非常に有益でした。 – WillyC

+0

ありがとう@WillyCあなたが説明が役に立つと思ってうれしいです。私は提案された解決策が素晴らしい(それはハッキリと感じる)わけではないことに同意しますが、それは私の目標であったあなたの問題がなぜ起こったのかを説明するのを助けたと感じました。実際のソリューションとして、私はおそらくフレックスボックスをこの場合最もクリーンなオプションとして選ぶでしょう。 – erikamjoh

1

私は周りを試して、あなたのHTMLで解決策を見つけませんでした。

しかし、あなたは、HTMLの構造を変更することができれば、あなたはフレキシボックス(複数可)を使用して所望の結果を達成することができます

#main-toolbar { 
 
    display: flex; 
 
    align-items: start; 
 
    min-height: 90px; 
 
    width: 100%; 
 
} 
 

 
.test { 
 
    border: solid red 1px; 
 
} 
 

 
.profile-toolbar-wordmark, 
 
.profile-toolbar-logoicon { 
 
    width: 90px; 
 
    height: 90px; 
 
    margin-right: 5px; 
 
    flex: 0 0 initial; 
 
} 
 

 
.wrap_right { 
 
    display: flex; 
 
    align-items: center; 
 
    flex-wrap: wrap; 
 
} 
 

 
#main-toolbar-text { 
 
    display: inline-block; 
 
    color: #2196f3; 
 
}
<div id="main-toolbar" class="test"> 
 

 
    <img class="profile-toolbar-logoicon" src="https://pixy.org/images/placeholder.png"> 
 
    <div class="wrap_right"> 
 
    <img class="profile-toolbar-wordmark" src="https://pixy.org/images/placeholder.png"> 
 
    <span id="main-toolbar-text"> 
 
    Why won't this text wrap? 
 
    </span> 
 
    </div> 
 
</div>

+0

HTML構造を変更する必要はありませんAFAIK – dippas

+0

何か - 少しシンプルに(つまり要素が少ない)IMOはより使いやすくなっています – Johannes

関連する問題