I'm making a horizontal scrolling site and encountering an issue where, when using flexbox, my content is pushed out of the page by my background image. Please see my pen:
https://codepen.io/anon/pen/NwgQmG
I'm using three background images that each take up a full page's width and inline-block to create horizontal scrolling.
In addition, I want to add flexbox so that I can create my own grid system on top of each background image. The problem is that when I add flexbox, I must use position: absolute on the first div below my background image so that the background image isn't pushed down to the bottom of the page.
<div id="homeImg" class="background-image-full">
<div class="container row" style="position: absolute;">
<div class="container column">
Hello There!
</div>
</div>
</div>
Then, when I attempt to add text to a container inside my grid system ("Hello There!"), the text does not show up. It's pushed to the upper left-hand corner, as indicated by inspect.
How can I get my text to show up? Is there a better way to use flexbox where I don't have to also use absolute positioning?
Thanks!
The problem is you set the font-size:0
Change it to some px value as I did it in this Codepen
Also you need to give position:relative to the same class i.e. .surroundContainer.
Which will make your container stick to the current image.
* {
margin: 0;
}
/*box-sizing will ensure an element stays within a parent width, even if padding or borders are applied.*/
*,
*:after,
*:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.wrapper {
height: 100vh;
background-color: gray;
}
.surroundContainer {
position: relative;
height: 100vh;
white-space: nowrap;
font-size: 20px;
color: white;
}
/* IGNORE: this is a class for a plugin */
.scroller {
/*This scroll-snap functionality only works in Safari*/
-webkit-scroll-snap-type: mandatory;
-webkit-scroll-snap-points-x: repeat(100%);
/*This scroll snap functionality is part of a polyfill
that enables the functionality in Chrome.*/
scroll-snap-type: mandatory;
scroll-snap-destination: 0% 100%;
scroll-snap-points-x: repeat(100%);
/*Here, I've set the width to be 100% of the VW
(the portion of the screen that the viewer sees before scrolling).
Thus, overflow occurs (because my divs stretch three screens or three VWs, basically)
and the scroll event from scrollsnap-polyfill.js is triggered.*/
width: 100vw;
overflow: auto;
}
.background-image-full {
height: 100%;
width: 100%;
display: inline-block;
background-size: cover;
background-repeat: no-repeat;
}
#homeImg {
background-image: url("https://www.petfinder.com/wp-content/uploads/2012/11/91615172-find-a-lump-on-cats-skin-632x475.jpg");
}
#AboutImg {
background-image: url("http://www.catster.com/wp-content/uploads/2017/08/A-fluffy-cat-looking-funny-surprised-or-concerned.jpg");
}
#CreditImg {
background-image: url("https://www.bluecross.org.uk/sites/default/files/assets/images/124044lpr.jpg");
}
.container {
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.row {
flex-flow: row;
-webkit-flex-flow: row;
}
.column {
flex-flow: column;
}
<!-- This is the wrapper for the entire page -->
<div class="wrapper">
<!-- This is the div that contains the horizontal scrolling -->
<div class="surroundContainer scroller">
<div id="homeImg" class="background-image-full">
<div class="container" style="position: absolute;">
<div class="column" style="border:5px solid white; height:300px; width:300px;">
<p>Hello There!</p>
</div>
</div>
</div>
<div id="CreditImg" class="background-image-full"></div>
<div id="AboutImg" class="background-image-full"></div>
</div>
</div>
Related
I want to show a canvas, possibly larger than the viewport.
The layout is common: navigation on the left, canvas, controls etc... on the right.
When the canvas is large, I want scrollbars around the canvas where needed. That's what the overflow=auto on the canvas div wrapper is for.
html {
height: 100%;
margin: 0;
}
body {
height: 100%;
margin: 0;
background: yellow;
}
.container {
display: grid;
grid-template-columns: fit-content(200px) 1fr;
height: 100%;
overflow: hidden;
background-color: #b30a96;
}
.navigation {
background-color: darkkhaki;
}
.right {
display: flex;
height: 100%;
flex-direction: column;
background-color: red;
}
.canvas-wrapper {
overflow: auto;
background-color: #DE8D00;
}
#canvas {
display: block;
background-color: #0bb314;
}
.rest {
background-color: aquamarine;
}
<div class="container">
<div class="navigation">
navigation
</div>
<div class="right">
<div class="canvas-wrapper">
<canvas id="canvas" width="2500" height="1800"></canvas>
</div>
<div class="rest">
rest...
</div>
</div>
</div>
With only the flexbox, I see scrollbars just fine. As soon as I embed the flexbox in the grid, no more scrollbars.
A number of related posts shed some light but got me no closer to solving the problem.
I tried various permutations of width, height, max-width, max-height, min-width, min-height on the wrapper, the flexbox, the grid, with no satisfying result.
Before resorting to JavaScript and forcing the size of the div wrapper, I would like to know whether this can be solved in pure CSS.
after setting
grid-template-columns: fit-content(200px) minmax(0,1fr);
in class .container and adding
min-height: 0;
to class .right, the scrollbars are finally visible around the canvas.
As I understand it, the problem was that the div wrapper didn't have a size, and setting a minimum of zero somehow helps.
I have a simple webpage with a main section that is 85vh and a "floor" which is 15vh. The floor element contains an image which I want to look like the floor of the page. It has a checkerboard pattern that fades to white and looks like a floor.
My current CSS is working pretty well, however, the problem I'm having is when the user makes the window skinny (less than 800px or so in width), the floor image stars to become really small and it doesn't look good and it doesn't look like a floor anymore.
What changes should I make to the CSS to make the image in the floor element looks like the "floor of the page", no matter what the width or height of the window is? It should probably be centered and adapt to the window width, but not get smaller than 1920px or so the floor looks the same size at any window width, but gets cropped automatically to adapt to the page width.
https://jsfiddle.net/z7w41vd5/
.wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
margin: 0px auto;
}
.main {
height: 85vh;
}
.floor {
height: 15vh;
min-width: 1920px;
width: 100vw;
}
.floor img {
width: 100%;
}
<div class='wrapper'>
<div class='main'>
</div>
<div class='floor'>
<img src='https://i.imgur.com/VuLVv68.png'>
</div>
</div>
Make it a background image instead of an <img /> and you'll be able to control it the way you want to.
.wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
margin: 0px auto;
}
.main {
min-height: 85vh;
}
.floor {
min-width: 1920px;
min-height: 15vh;
background: url(https://i.imgur.com/VuLVv68.png) bottom center;
}
<div class='wrapper'>
<div class='main'></div>
<div class='floor'></div>
</div>
Alternatively, you could make it the background of the <body> and remove the floor element from your html entirely.
html {
height: 100%;
}
body {
background: url(https://i.imgur.com/VuLVv68.png) bottom center no-repeat;
min-height: 100%;
}
.wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
margin: 0px auto;
}
<div class='wrapper'>
<div class='main'></div>
</div>
I want to center .donut-graphs inside .dashboard horizontally, so the space between the right edge of the sidebar and the left edge of .donut-graphs is the same as the space from the right edge of .donut-graphs and the right edge of the screen. I have managed to do so, but I had to remove position: fixed from .navbar. The problem is, I can't do that because my sidebar has to stay on top of the screen when you scroll up/down, and with position: fixed on .navbar, the graphs aren't centered properly.
HTML:
<div class="container">
<div class="navbar">
</div>
<div class="content">
<div class="dashboard">
<div class="donut-graphs">
<div class="dashboard-income">
Div 1
</div>
<div class="dashboard-overall">
Div 2
</div>
<div class="dashboard-spent">
Div 3
</div>
</div>
</div>
</div>
</div>
CSS:
body {
margin: 0;
}
.container {
display: flex;
align-items: stretch;
max-width: 100%;
min-height: 100vh;
}
.navbar {
background-color: #ddd;
flex: 0 0 230px;
position: fixed;
height: 100vh;
width: 230px;
}
.content {
flex: 1;
overflow-x: auto;
text-align: center;
}
.donut-graphs {
display: inline-flex;
border: 1px solid;
margin: 50px auto 0;
position: relative;
text-align: left;
}
.dashboard-income,
.dashboard-overall,
.dashboard-spent {
height: 256px;
width: 357px;
display: inline-block;
}
.dashboard-income {
background-color: green;
}
.dashboard-overall {
background-color: blue;
}
.dashboard-spent {
background-color: red;
}
How can I overcome the issue?
Demo
position: fixed puts element above everything. That element won't attach to any element in body because it is the way that works. It only becomes dependent of viewport
What you want to achive could be done with position: absolute but parent (whose child you want to center) has to be position: relative for this to work.
Read more about positioning elements in css here
.content { padding-left:230px; }
Should do the trick.
Assigning your navbar a fixed position takes it out of the document flow, so when centering your donut graphs the browser doesn't take the navbar into account.
Giving the .content element a padding equivalent to the width of the navbar makes up for this.
The only problem with this approach is that if .navbar changes dimensions, you'll need to change the padding on .content to match.
I have this following html code in my page:
<div class="container"> (Can't have static height)
<img></img> (Has variable height)
<label></label> (Has variable length)
</div>
I want to align both of them in a same line vertically applied in any browser. If it's possible by a standard way how should I work?
I have searched and read a lot of articles to fix this problem but it wasn't worked.
Edit: The "container" div in this case isn't the main container div in page and it has 3 other parents above itself that they have no effect on position of it.
You can use flex by adding :before and :after with flex:1 which will make the image/text always in the center. Then you can use flex again for image and text to make them aligned in the same line like this:
Go full page to see the result better
* {
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
}
.page {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
}
.page:before,
.page:after {
content: " ";
flex: 1;
}
.container {
display: flex;
align-items: center;
}
label {
padding: 5px;
}
<div class="page">
<div class="container">
<img src="https://lorempixel.com/200/200/">
<label>text</label>
</div>
</div>
You could use text-align, display and line-height like the following:
<style>
.container{
text-align: center;
}
.container label{
display: block;
line-height: 0; /*To stick the label under the bottom edge of the image*/
}
.container img{
display: inline-block;
}
</style>
Checkout this DEMO
I'm trying to center an element in the middle of the page. I can center it just fine, but if I resize the page vertically until the view height is smaller than the centered element, the element goes offscreen vertically without a scrollbar. You can see a demonstration of the issue here:
http://codepen.io/mse/pen/BWayXV
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
}
.outer {
text-align: center;
position: relative;
top: 50%;
transform: translateY(-50%);
}
.inner {
display: inline-block;
width: 400px;
height: 800px;
background: grey;
}
<div class="outer">
<div class="inner"></div>
</div>
I should mention that I have tried a couple of other methods of vertical centering, including flexbox, and I'm still running into the same issue. Is there a way to solve this problem with this method of vertical centering, or is there at least a vertical centering method that does not have this issue?
Try this
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
}
.outer {
display:flex;
justify-content:center;
align-items:center;
}
.inner {
background: #ccc;
width: 400px;
height: 600px
}
<div class="outer">
<div class="inner"> I'm a block-level element centered vertically within my parent.</div>
</div>
More info: https://css-tricks.com/centering-css-complete-guide/
CSS VH center generator: http://howtocenterincss.com/
This should work
* {
padding: 0;
margin: 0;
}
html, body {
height: 100vh;
}
.outer {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.inner {
width: 400px;
height: 800px;
background: grey;
}
<div class="outer">
<div class="inner"></div>
</div>
You can try to limit the size of your inner element. If you define size by a fixed px amount it will start scrolling as soon as the screen becomes smaller than that px amount. If you are ok with changing the height of the inner element you could use vh or you can implement #media queries to decrease the size on smaller screens. Here#s an example:
.inner { height: 100vh; /* 100 view height percentage*/}
Note: The viewport-percentage lengths are relative to the size of the initial containing block and affected by the presence of scrollbars on the viewport.