I have a two column layout, where the left side consists out of a menu that should stick and the right side contains a long form. On the bottom of the page is a footer:
There are two problems with this:
If the browser window is smaller then the menu height, it is not possible to see the lower menu items as it is fixed and therefore does not scroll.
If one scrolls down the form to the bottom, the menu will hide the footer
My CSS looks like this:
#menu_side{
color:black;
background-color: #ffffff;
margin:67px 5px 5px 5px;
position: fixed;
width: 250px;
}
As an alternative mentioned inside the comments, one could use a container for the menu and use vh. Unfortunately this seems not to work as the inner elements simply outgrow the div. Illustrated in this img with a red border for the container:
How could I manage to keep the menu in sight of the user while he scrolls down the form and in the same time solve the mentioned 2 problems? Thank you for any help on this.
You should wrap #menu_side in a new container and let that container be fixed and make sure its height equals the viewport height. This can be done with vh units or with Javascript.
<div class="menu_container">
<div id="menu_side">
<!-- your menu -->
</div>
</div>
CSS:
.menu_container{
position: fixed;
height: 100vh;
width: 260px;
left: 0;
top: 0;
}
#menu_side{
margin:67px 5px 5px 5px;
}
As for your second issue: This can best be achieved using Javascript. You could for instance calculate the visible height of the footer element and use Javascript to calculate the appropriate height for .menu-container
Related
I want to create a simple side-navigation that takes up the entire screen's height. I am using Milligram for my base, and I want my side-nav to work with it. I have the following set up:
Codepen demo
As you can see, my sidebar is the following element
<div class="sidebar"></div> with the following styles:
div.sidebar {
position: absolute;
width: 250px;
height: 100%;
z-index: 99;
background-color: black;
}
This sort of works, the sidebar appears above all else, but everything else does not get pushed to the side. And if the screen is small, the content clashes with the sidebar.
How can I make it so the sidebar pushes everything else (including the navbar) to the right by 250px(its width)? I know this will make things unusable on smaller screens, but I will give the user a way to toggle it.
Any help is appreciated.
You can set the left margin on your equal to the width of your sidebar.
section .container {
margin-left: 250px;
}
I've run into an issue with the page I'm working on. The basic idea of the page is it is a list of items and you click a row to go the a details page for that item, fairly straight forward. My issue is with the CSS.
Basically almost everything on the page is static (doesn't scroll) and just the stuff in the table scrolls (yes, I hid the scroll bar). I was able to accomplish this using a good bit of positin:fixed; but now I've got a problem.
Each category has its own page with a table (categories are the links on the left side). Some categories require extra buttons along the top, like a second row of blue pill buttons. The problem is that the second row of buttons makes the top area larger so the table has to be smaller. But, since most of the page is position:fixed; the size of the scrolling table is based on the sizes of the fixed regions around it using `height:calc(100vh - 170px);' But when there is a second row of buttons the 170px no longer works.
So here is the question: Is there a way to accomplish the scrolling behavior required via pure css with a variable sized row of buttons?
I've tried several things including flexbox but in the end I can't seem to get this to work without setting the height of the table body using the calc function.
It sounds like what you need is flexbox. You have a header section that determines the height of a content section, essentially. Flex columns with grow/shrink parameters accomplish this.
.container {
bottom: 0px;
display: flex;
flex-direction: column;
left: 0px;
position: absolute;
right: 0px;
top: 0px;
}
.container > .header {
background: yellow;
flex-shrink: 1;
}
.container > .content {
background: black;
color: white;
flex-grow: 1;
}
<div class="container">
<div class="header">
Header content<br>
This will keep expanding in height.
</div>
<div class="content">
The height of this black content box depends on the height of the header above.
</div>
</div>
Code: https://jsfiddle.net/gsnfzn35/3/
It's a bit funky to describe, click the toggle drawer button. A pull out drawer on the right shows up. That pull out drawer is one container, but has 2 key components. The first component is all the content at the top. The last component is a "fixed row" on the bottom:
<div class="scroll-fixed-row" style="width:100%;text-align: right">
<p>
FIXED FINAL ROW
</p>
</div>
This row SHOULD be the width of the pull out drawer, whatever that width is; NOT the width of the screen. Currently though, if you inspect element with the width:100%, you see that the width is the width of the screen, not the pull out drawer. Another way to see this is in the fact that when there's width:100%;text-align:right, the text is off screen, pulled to the right of the row that is too wide. Remove the width:100% and you can see the text again.
I'm guessing this is due to the fact that the scroll-fixed-row is fixed, and therefore, its taking width from the screen, not the pull out drawer itself. But this fixed is necessary, because that scroll-fixed-row needs to stay at the bottom even though the rest of the pull out drawer scrolls. Given that constraint, how can I set the width of the scroll-fixed-row to be the width of the pull out drawer, for any screen (full responsiveness) WITHOUT having to provide specific width in pixels based on media queries?
The reason I'm asking this is because I would like to divide the scroll-fixed-row into 2 "sections" using either a table and 2 <td width="50%"> or using Bootstrap grid and 2 <div class="col-xs-6"> in a row. In the current implementation (NOT in the Fiddle), the content in the 2nd grid just gets pushed off page (same issue now) because the table width is inheriting from the screen. I think I can figure that part out if someone can help me answer this question.
The width can be solved by using inherit instead of 100%, this will make a fixed element get the width of its parent, in your case .container.scroll. I noticed that you have padding added to parent, the inherited width will include paddings and so the fixed element will overlay the scrollbars.
Code:
.scroll-fixed-row {
position: fixed;
text-align: right;
background-color: white;
border-top: 1px solid black;
width: inherit; /* get width from parent */
bottom: 0; /* stick to bottom */
right: 0; /* fix offset caused by padding */
}
Another thing I noticed that in your code is that you are using margin-top: 70px on .scroll to offset it from the fixed red nav, this causes the the bottom part that is out of viewport to be invisible, especially the bottom scroll arrow. I've changed it to the following:
.scroll {
position: fixed;
top: 70px; /* offset from top (nav height) */
height: calc(100% - 70px); /* calculate height minus the top offset */
}
If you wanted to prevent the fixed element from overlapping the scrollbars, you could apply pointer-events: none and add another wrapper in the HTML that gets a 15px spacing like the content, for better consistency:
.scroll-fixed-row {
...
pointer-events:none; /* disables mouse functionality to enable scrollbar control */
}
.scroll-fixed-row .inner {
border-top:2px solid red;
background:lightblue;
margin:0 30px 0 15px;
pointer-events:auto; /* allows mouse functionality */
}
jsFiddle demo - scrollbar overlap: https://jsfiddle.net/azizn/guufj4a0/
jsFiddle demo - additional wrapper: https://jsfiddle.net/azizn/d6wwk51b/
I've got this problem, I've placed a div within a div, I've positioned the "title" to be height 50, and then "navbar" below it, so I've put height 100% though the thing is, its not staying within the div, its actually straying away from and out of the div and making a scrollbar appear.
I would love "site" to hog the walls and then all the other div fit in that div.
<div id="site">
<div id="title">TitleBar</div>
<div id="navbar">NavBar</div>
<div id="frame">FrameBar</div>
</div>
body{
margin: 0;
}
#site{
position:absolute;
width: 100%;
height: 100%;
*border: 1px solid #333;
}
#title{
border: 1px solid #333;
height: 50;
}
#navbar{
border: 1px solid #c38a8a;
width: 200;
height: 100%;
}
I've found an image that shows something similar.
http://img176.imageshack.us/img176/4637/picture1zb1.png
that's because 100% height actually means "use the same height as the container".
But I didn't quite get all your requirements for this layout, if your navbar is a navigation bar, it should be designed in a way that allows scrollbars to appear when the content is too big.
But I think you're going for the wrong structure to accomplish this, is there any actual reason you want a wrapper div? I've created a fiddle on this, check if this is closer to what you wanted: http://jsfiddle.net/6g6HV/2/
This other one is yours, in case you wanna play with it: http://jsfiddle.net/yq8PS/3/
Edit: Adding the javascript solution to the answer http://jsfiddle.net/6g6HV/9
You can make divisions in HTML appear side by side to each other by adding a float property to the css.
#navbar{
border: 1px solid #c38a8a;
width: 200px;
height: 100%;
float: left;
}
Additionally, always add the 'px' unit after a size. Modern browsers assume you mean px, but older ones might not.
There isn't a good way to prevent the overlapping when you have a sidebar that is a set pixel width. To achieve the liquid width (or fluid width) style, you would have to add negative 200px margin on the left to the #frame (to counter sidebar). Then, add another divsion inside the #frame to do the styling for that portion. This is how I have achieved the look on my web site, and it's also the solution used in the previous default Drupal theme (Garland).
#frame{
margin-left: -200px;
}
IN this context, 100% for the Navbar doesn't mean the remaining height but 100% of the visible heigth of the parent; so if the parent has a height of 400px then Navbar will also have an height of 400px. If you add to this size the height of the title bar, you get a total value greater than the size of the parent; therefore the appearance of the scolling bar.
While there is usually no problem with the width to make it appears to fill the whole length of a screen, it's very difficult in HTML & CSS to do the same with the height as they have not been designed for this sort of thing; especially with an imbricated structure (div inside div).
Some people will use Javascript to get the size of the screen (browser) and compute the size of their objects accordingly but I don't know if you can do the same with a pure HTML/CSS solution; especially if you want to have your solution compatible accross many browsers.
For more info, take a look at http://www.tutwow.com/htmlcss/quick-tip-css-100-height/
I'm writing a mobile/desktop chat application that is supposed to utilize the entire screen. The bottom <div> shown in yellow can be fixed-height if it needs to be.
presently it's Absolutely positioned to the bottom of the window.
My problem: the top <div>, in cyan, doesn't fit to the rest of the window, regardless of whether I use padding, margin, border, etc. Presently it appears to allow the content to wrap, but that's only because the bottom overwrites the scroll bar.
My only solution so far is to have a final <div> or <br> that pads the end of the scrollable div, but that doesn't make the div smaller, or make the scroll bars properly align.
Here is my source code so far in Fiddle.
Can you edit your CSS and set the DIV with the chat text a class like .break-word and then in CSS declare it with word-wrap:
.break-word {
word-wrap: break-word;
}
Unsure on the covering of scrollbars. You should post your code for others to view and might be able to pick something out.
This style code basically sums up what I'm doing to compensate for my issue. (Instead of, say, using HTML tables.) This may not be the best solution.
#topPart {
position: absolute;
width: 100%;
top: 0;
bottom: 40px; /* or however high the bottom is */
}
#bottomPart {
position: absolute;
width: 100%;
bottom: 0;
height: 40px; /* same as above */
}