Reputation: 6372
I have a div that's "floated" to the centre with display:table; margin:auto;
(green box)
Inside this, I have a float:left
element (red box, which is not always present), then a number of display:block;
"lines" (lime boxes). The application is poetry formatting with drop capitals and reverse indentation:
https://jsfiddle.net/nktj94gd/2/
The problem is that the floated "L" is "stealing" its own width from the lime blocks, rather than allowing the outer block (green) to expand to prevent the lime lines wrapping when they do not have to.
I'd really like to avoid having lines wrap when they don't have to, but I cannot set the width of the overall box (it could be from a few em to 100%) .Is there a way to achieve this?
Upvotes: 0
Views: 40
Reputation: 101
you probably found some more practical solution to this a year ago, but this is a fairly obscure problem I ran into while also styling poetry, so I figured I'd post my solution in case anyone else needs it :) Hope your poem project worked out, OP!
I think probably most people use <br />
and ::first-letter
or something and thus never run into the problem. It's ultimately just a problem of how to preserve intended whitespace (linebreaks mainly) with a pretty dropcap, which is niche, but falls apart quick if you're designing responsively and avoiding hard breaks. (I was using whitespace: pre
because it had indented stanzas) ¯\_(ツ)_/¯
display: block
on the spans to display: table-row
; since your outer is display: table
, and you don't impose widths anywhere here, the 'table' will simply expand to accommodate both the float and the lineboxdisplay: table-caption
on an inner part of the dropcap (not truly necessary, but in OP's code so why not: https://jsfiddle.net/thn2x5zc/)This is responsive and doesn't care what your drop cap is. It runs into overflow issues if the drop cap and poem are both too big, you can shove whatever behaviour you want on this bad case if you want (like overflow: hidden
on the dropcap, controlling their whitespace/widths, etc....)
It does care about your container structure and margin collapse a lot, so if your code were different, you'd need a different display
value, likely something putting table-row/table-cell on a block.
Of course this does have quirks relating to how browsers treat table elements by default, though - mainly auto-collapsed borders, like in a <table>
.
::first-letter
pseudo-selector, white-space: pre, margin/padding etc. (things other people might use) see: https://jsfiddle.net/3oghpj0w/These things are all very janky/contradictory secretly, but since ::first-letter
is a pretty standard way to style drop caps, and marking up/styling your lines individually may be inconvenient, it is how I ran into the problem lol.
If it's ::first-letter
, we're using a block-level element to hold the poem text. The most basic way is just to apply width: min-content;
to that block's container to get it to sort of take away the float's contribution (since it's larger). Then you can add padding-right
to that container to re-accommodate borders, margins, etc. (If the margin between the drop cap and poem is 3em, add 3em back to the right.)
Fixes of this style do not re-integrate the float with the poem, so the poem will still have overflow issues. But it's sufficient for fixing simple alignment problems :)
Sorry this is so long! A lot of conventional fixes break when you care about the shape of the whitespace and can't treat text as a block, which makes a lot of search results very inapplicable.
Upvotes: 0
Reputation: 273031
I would use an extra wrapper inside that I make slightly bigger considering the width of L
.outer {
display: table;
margin: auto;
overflow:auto;
outline: 1px solid green;
}
.outer > div {
width:calc(100% + 2.8em); /* 2.8em is an approximation of L width */
transform:translateX(-1.4em); /* rectify the centring */
}
.dropcap {
float: left;
}
.dropcap-inner {
font-size: 4em;
line-height: 1em;
margin-right: 1em;
border: 1px solid red;
}
.line {
display: block;
text-indent: -4em;
margin-left: 4em;
border: 1px solid lime;
}
<div class="outer">
<div>
<span class="dropcap"><span class="dropcap-inner">L</span></span>
<span class="line">orem ipusm dolor sit amet</span>
<span class="line">Lorem ipusm dolor sit amet dddd</span>
</div>
</div>
Upvotes: 1