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
P粉6210339282024-04-02 11:59:47
CSS IssuesCause you are experiencing problems:
.*, *:before, *:after { }
, there is an initial .
(dot) that is easy to miss. Therefore the border-box
model only works with :before
and :after
pseudo-elements. Apparently, the same goes for margin
and padding
. .panel
ancestors have no width
value set, so flexbox cannot constrain child elements and will grow to infinity. flex: 0.5
(default is flex: 0.5 1 0%
) obviously has no effect since it has no width flex-basis: 50%
. In both cases, the pre 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 and gap
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 because gap
will increase the total width of .panel
s, possibly causing them to overlap when resized. Since your ngap: 1rem
adds 0.5rem
to each of the two columns, you need to subtract that value from the width
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 extra calc(..)
in CSS is to move the element's margin
to its immediate parent's padding
. 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 chose 300px
. .panel
element to grow to its full 50%
when unwrapped. Also hyphen
ate text to improve readability...
fragment
*, *: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 {
background: #d7d7db;
display: block;
overflow: auto;
white-space: pre;
padding: 1rem;
}
.container {
background: #0197f4;
display: flex;
flex-direction: column;
padding: 1rem;
width: 100%;
}
.box {
background: #ff7538;
display: flex;
flex-flow: row wrap;
gap: 1rem;
padding: 1rem;
}
.panel {
background: #fff;
display: flex;
flex-direction: column;
padding: 2rem;
/* Adjust for parent gap value */
width: calc(50% - 0.5rem);
/* Allow to grow and wrap when less than 300px */
flex: 1;
min-width: min(300px, 100%);
}
.text { hyphens: auto }
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi accumsan mattis ullamcorper. Nulla tincidunt aliquam feugiat. Sed imperdiet tellus ligula, vehicula condimentum neque venenatis ut. Aenean varius elementum nulla, vehicula laoreet erat aliquam at. Nullam venenatis ex id tincidunt fringilla. Vivamus nec tellus sit amet leo tristique luctus. Cras elementum at diam at viverra. Phasellus tristique elementum velit id tincidunt. Nullam ullamcorper fringilla nulla sed ultricies.
function SomeFakeFunction(first_argument, second_argument) {
if (first_argument > second_argument) {
return "first argument is greater than second argument";
} else if (first argument < second_argument) {
return "first argument is less than second argument";
}
return "first argument and second argument are equal (or invalid but this is just filler code so i don't care to write anymore honestly)"
}