I have some code inside pre
and code
tags in a bootstrap container that I'd like to scroll horizontally. This normally works fine, until I add a flexbox to my page's body
in order to accomplish a sticky footer. After this, the code
no longer scrolls horizontally when the page is narrow (such as for mobile viewing).
Here's my code (note that horizontal scrollbars for the code
go away as you narrow the window):
html, body {
height: 100%;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
}
code {
max-height: 200px;
background-color: #eeeeee;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
}
.flexer {
flex: 1;
}
footer {
background-color: #CCC;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-12 docs">
<p>Some sample code</p>
<pre><code>Loading mirror speeds from cached hostfilebase: mirrors.arpnetworks.com * centosplus: mirrors.arpnetworks.com* extras:mirrors.arpnetworks.com*rpmforge: mirror.hmc.eduupdates: mirrors.arpnetworks.comExcluding Packages in global exclude list</code></pre>
</div>
</div>
</div>
<div class="flexer"></div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
footer
</div>
</div>
</div>
</footer>
http://jsfiddle.net/nturor46/1/
Any idea how to use flexbox for sticky footers while still maintaining scrolling pre
/ code
?
a simple
.container { width:100%; }
resizes the website correctly. BUT then, Chrome doesn't let you actually use the scrollbar. This is caused by it overflowing the dimension of all of its containers (apart from BODY). Hence we gotta tell the browser to correctly recognize the pre node:
.container {
max-width: 100%;
}
pre {
position: relative;
}
This tells Chrome to correctly handle mouse events again AND fixes the layout
Please note that the margin-bottom of the pre
-node is lost in overflow-country, which could cause your layout to look weird. max-width
was used in the final version to make sure it doesn't overwrite fixed width statements made in bootstrap
PS: tested in current Chrome and Firefox http://jsfiddle.net/nturor46/32/
Those bootstrap styles just wreak havoc on natural CSS!
The problem seems to come from a conflict between your column
-direction flex container and bootstrap rules. It's basically resulting in the horizontal scrollbar shifting from the pre
/ code
content box to the browser window, when the content box overflows the screen.
With these adjustments, your desired layout seems to work:
.container
div the primary flex container (in your code this role is played by the body
element)footer
element into this new containerauto
margins to stick the footer to the bottommargin
, padding
and width
wherever necessaryHTML
<div class="container">
<div class="row">
<div class="col-md-12 docs">
<p>Some sample code</p>
<pre><code>Loading mirror speeds from ... cached hostfilebase</code></pre>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
footer
</div>
</div>
</div>
</footer>
</div>
CSS
html, body { height: 100%; }
body > .container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%; /* override bootstrap styles */
padding: 0; /* override bootstrap styles */
}
body > .container > .row {
margin: 0; /* override bootstrap styles */
display: flex; /* nested flex container */
justify-content: center; /* center content box on page */
}
body > .container > .row > .docs {
width: 75%; /* adjust width of the content box here */
}
code {
max-height: 200px;
background-color: #eeeeee;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
}
footer {
margin-top: auto; /* stick footer to bottom of container */
background-color: #CCC;
}
Revised Fiddle
Tested in Chrome and Firefox.
What happens here is most definitely a bug in Chrome.
After playing around with your Fiddle, and looking at it with other browsers, I can conclude that this is a Chrome-specific problem. And a curious one.
For some reason, <div class="col-md-12 docs">
grows to the size it should have (the height of p
and pre
together), but doesn't account for the horizontal scrollbar inside the pre
tag.
Here's an image to demonstrate the problem. The part with the red background is the container.
Since pre
has a border of 1px wide at the bottom, the result leaves a 1px gap for you to actually use the scrollbar. You can try it yourself. Just try to grab the most upper 1px line of the scrollbar.
Removing the flex properties does fix your problem, but we're not going to accept that.
Now, I would've thought that adding a padding of 0.1px to the bottom of the parent would fix the problem, but it didn't. I then tried wrapping the pre
tag in a div
with class chromefix
, and then added the following CSS
.chromefix{
overflow: hidden;
}
But that created an even weirder situation where the container grew with the scrollbar for about 50%
So I tried combining the two, but not a lot of difference there.
This is where I started looking at the pre
tag and its properties. It has overflow: auto
by Bootstrap default. So what I tried was adding
pre{
overflow-x: scroll !important;
}
And guess what? It worked!
So all you have to do is add overflow-x: scroll !imporant
to pre
, and you're good to go! Here's a working Fiddle.
Hope this helps
As a sidenote. I think you want to move max-height: 200px
to pre
as well. It won't work when you've applied it to code
.
Problem seems to be with the width of <pre>
.
When width of your screen goes below 768px
no specific width is applied to the .container
by bootstrap hence the issue is occurring.
When width of your screen is above 768px
following classes from bootstrap.css
come in picture.
@media (min-width: 1200px)
.container {
width: 1170px;
}
@media (min-width: 992px)
.container {
width: 970px;
}
@media (min-width: 768px)
.container {
width: 750px;
}
As you can see once the width goes below 768px
there is no specific width given.
To counter this issue, you have to write your css, something like this.
@media (min-width: 480px) {
.container {
width: calc(100% - 40px);
}
}
Basically, you have to specify width for .container
when screen width goes below 768px
. Once you do, it will fix your issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With