I apply CSS to the pre code
selector in order to make styled code blocks like you would see on GitHub or elsewhere. I'm using Flexbox for layout and have two "panel" divs side by side inside a "box" div, one of which has a code block (this is just the code inside the <pre><code>
tag) , and the "box" div is inside the main "container" div.
The basic CSS I have is...
.*, *:before, *:after { margin: 0; padding: 0; box-sizing: inherit; } html { box-sizing: border-box; } body { display: flex; align-items: center; justify-content: center; } pre code { display: inline-block; overflow: auto; white-space: pre; padding: 1rem; margin: 1rem; } .container { display: flex; flex-direction: column; margin: 1rem; gap: 1rem; } .box { display: flex; flex-direction: row; gap: 1rem; } .panel { display: flex; flex-direction: column; flex: 0.5; padding: 1rem; }
Since flex: 0.5
, both panels should be equal in width, but the right panel expands to fit the block instead of the block shrinking to fit the panel.
If I set white-space: pre-wrap
on pre code
, I get the desired layout behavior, but of course the code is wrapped, which is what I Unwanted.
white-space: pre
and add a dedicated width to the pre code
, I get the desired behavior, where the code block has a horizontal scrollbar. I can't use a dedicated width because I need the block to fit any panels inside it.
For some reason, setting width: 100%
on the pre code
has no effect at all.
To make sure I wasn't doing something else somewhere that would cause this error, I put together this code to confirm my problem (I did add some background color and margins to make the container visible):
https://codepen.io/evprkr/pen/poKQXJr
CSS IssuesCause you are experiencing problems:
.*, *:before, *:after { }
, there is an initial.
(dot) that is easy to miss. Therefore theborder-box
model only works with:before
and:after
pseudo-elements. Apparently, the same goes formargin
andpadding
..panel
ancestors have nowidth
value set, so flexbox cannot constrain child elements and will grow to infinity.flex: 0.5
(default isflex: 0.5 1 0%
) obviously has no effect since it has no widthflex-basis: 50%
. In both cases, thepre code
will not trigger overflow, so the scrollable box will not be displayed. I can't explain why, but it must be due to some W3C specification. However, your declaration of.panel width: 50%
finally solved the problem.margin
s in conjunction with various elements andgap
can produce seemingly unexpected overlap of elements when resizing the browser/codepen. Even if the above initial.
solution
.
(click).container width: 100%
to provide a usable constraint for flexbox..panel flex: 0.5
and specify.panel width: calc(50% - 0.5rem)
.calc(..)
is required becausegap
will increase the total width of.panel
s, possibly causing them to overlap when resized. Since yourngap: 1rem
adds0.5rem
to each of the two columns, you need to subtract that value from thewidth
of each column.ngap
,margin
increases the overall width of the element, which requires you to subtract the left and/or right margins from the element width to prevent them from overlapping other elements. The easiest way to avoid adding extracalc(..)
in CSS is to move the element'smargin
to its immediate parent'spadding
. This isn't true in all cases, but in this case it works well without changing the overall layout.bonus
For Response Behavior:
.box
to wrap its child elements.panel width
to force the.box
to wrap its child.panel
s. In this case I chose300px
..panel
element to grow to its full50%
when unwrapped.Also
hyphen
ate text to improve readability...fragment