I want to have three vertically stacked divs.
The first div is at the top, it has a fixed height of 60px.
The middle div may or may not contain content, it will often contain content vertically larger than it, so it is set to overflow: auto. Regardless of if it contains content or not, it must consume the rest of the window's height minus the first div's height and the last div's height.
The last div has a minimum height of 40px. This div accepts user input, and can have a height between and up to 400px. This div expands upwards as the user inputs text, once it has reached the max height, it scrolls.
Here is a diagram:
+-----------+
| Header |
+-----------+
| ^|
| ||
| Scroll ||
| ||
| v|
+-----------+
| ^|
| Footer ||
| v|
+-----------+
I am having trouble getting the second (middle div) to shrink as the third div expands. I would like to accomplish this without js if possible.
CSS Tricks: A guide to Flexbox in combination with max-height.
*See new fiddle below
additional footer CSS:
.footer {
position: absolute;
bottom: 0;
width: 100%;
max-height: 400px;
background: #efefef;
}
Is that what you are going for?
EDIT:
NEW FIDDLE
I've actually implemented something like this before for a chat client. I don't have it to hand but this was the gist of it! I added a few styling niceties and the text entry mechanics so you can get an idea of how it would work.
I'm afraid it doesn't make the middle section shrink persay, but it does appear to get smaller. As the footer expands with its text it extends over the top of the middle block.
var inputBox = document.getElementsByClassName("footer")[0];
var contentBox = document.getElementsByClassName("content")[0];
inputBox.addEventListener('keydown', function(e) {
if (e.keyCode == 13) {
e.preventDefault();
createMessage(inputBox.textContent);
inputBox.textContent = "";
}
}, false);
function createMessage (str) {
var message = document.createElement('div');
message.style.cssText = "background: #3AF; padding: 10px; border-radius: 5px; margin: 10px 0; color: white;";
message.textContent = str;
contentBox.appendChild(message);
}
createMessage("Sent messages appear here!")
createMessage("Type a message in the footer and press enter to send")
createMessage("This list will become scrollable if there is enough content")
createMessage("The text entry will also dynamically resize as you type")
/* border box reset, as per http://www.paulirish.com/2012/box-sizing-border-box-ftw/ */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
/*
base container class, height can be relative or absolute (but it must have height
requires position relative or absolute so we can position the header and footer
finally requires vertical padding the same height as the the header/footer
*/
.container {
height: 600px;
background-color: rgb(220, 220, 220);
position: relative;
padding: 50px 0;
}
/*
header class, must have a height and width
should be top 0 and left 0 so that it positions inside the containers padding
must be positioned absolute
*/
.container .header {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 50px;
background-color: rgb(120, 120, 120);
text-align: center;
line-height: 30px;
padding: 10px;
color: white;
font-size: 22px;
}
/*
content box, the easiest really
height to 100% (so it will be the container minus the padding, which the header/footer sits in)
overflow-y: auto; so if we exceed the size of the content box we scroll instead
*/
.container .content {
height: 100%;
overflow-y: auto;
padding: 10px;
}
/*
positioned absolutely again, but bottom left this time.
use min height to specify the basic height then as the user types it will grow accordingly
set max-height to prevent it growing too tall, overflow: auto; again so we can scroll in that situation
VERY IMPORTANTLY MUST HAVE THE CONTENT EDITABLE FLAG ON THE HTML ELEMENT
*/
.container .footer {
position: absolute;
bottom: 0;
left: 0;
min-height: 50px;
max-height: 300px;
width: 100%;
overflow-y: auto;
background-color: rgb(120, 120, 120);
padding: 15px;
line-height: 20px;
color: white;
}
<div class="container">
<div class="header">HEADER</div>
<div class="content"></div>
<div class="footer" contenteditable></div>
</div>
The JS section isn't required, I've added it to the example to give it a bit more life.
It attaches a listener for the "enter" key on the text entry and uses the text to create a new "message" inside the content box. The actual layout is all done in CSS.
Related
I have a UI built in vue.js that I need to add tooltips to. I need the tooltips to be placed to the left or right of a specific div in the UI. I've been able to get my desired look by setting the tooltips to position absolute but this is not responsive so on some screens the tooltip does not align with the target div.
The UI is fairly complex so I'm trying to avoid having to rebuild the layout with flexbox/grid. I'm looking for a way to 'anchor' the tooltip to its corresponding divs using javascript.
https://codepen.io/joeymorello/pen/ZEeWmGd Here I am playing with append to and insertBefore but I would still need to fine-tune each tooltip location using CSS. Is there a way to just anchor one div right next to another div so the tooltip always follows its parent div?
const head = document.querySelector('.head')
const body = document.querySelector('.body')
const toolTipOne = document.querySelector('.tool-tip-1')
const toolTipTwo = document.querySelector('.tool-tip-2')
$(toolTipOne).appendTo(head);
$(toolTipTwo).insertBefore(body);
Apply position: relative to .body and append the tooltip inside it. Then you can easily position it with absolute relative to position of .body using top, left etc:
https://codepen.io/tilwinjoy/pen/QWpNJdY
Why not use pure css for this? You can use position relative on the element, then use its pseudo ::after element and set its position to absolute. Then call on the left, top, right and/or bottom properties to place your pseudo element on the page relative to its parent that has position relative set.
// example of how to change the content of a pseudo tag with JS and CSS variables using the root element
let root = document.documentElement
let headTTInfo = 'Maybe you want to change the Head tooltips content via JS?'
let bodyTTInfo = 'Here is content for your body elements tool tip generated with JS.'
root.style.setProperty('--body', `"${bodyTTInfo}"`)
root.style.setProperty('--head', `"${headTTInfo}"`)
:root {
--head: 'this is content for your head elements tool tip';
--body: 'this is content for your body elements tool tip'
}
/* This min-width on the body will ensure that your absolutely positioned element
is within the body and its display is not completely taken out of the
viewable container,
125px(tooltip offset) + 500px(width of parents) + 125px(tooltip offset) = 750
gives us 10px padding on each side if screen width less than the width of the
parents elements, we do this because postion absolute takes its positioned elements
out of the normal flow of the document. */
body {
min-width: 770px;
}
.head {
margin: 0 auto;
width: 500px;
height: 250px;
background-color: green;
position: relative;
}
.body {
margin: 1rem auto;
width: 500px;
height: 250px;
background-color: pink;
position: relative;
}
.head::after {
content: var(--head);
position: absolute;
left: -125px;
top: 40%;
width: 100px;
height: auto;
padding: 5px;
background-color: teal;
}
.body::after {
content: var(--body);
position: absolute;
left: 515px;
top: 40%;
width: 100px;
height: auto;
padding: 5px;
background-color: orange;
}
<div class="container">
<div class="head">HEAD</div>
<div class="body">body</div>
</div>
I want to have my footer at the bottom of the page. If the page is long enough, I want to have to scroll to the footer. If the page is too short, I still want my footer at the very bottom of the viewport. I don't mind the empty space.
How can I achieve this as painlessly as possible?
I tried navbar-static and nav-bar fixed and they both don't do what I am looking for. Is filling the space with a spacer div or something the only way or is there a more elegant way using CSS3 or some javascript?
Open to any and all ideas/suggestions.
This is the HTML I have. Nothing special coz I tried position: absolute;bottom:0px; and that put the footer at the bottom of shorter pages but in longer pages the bottom hangs in the mid of the page overlapping content.
This code puts the footer at the bottom of the page but in pages which are shorter than the window/viewport the footer sort-of hangs in the middle (at the end of the content).
.body
{
height: 100%;
}
.bottomMenu
{
background-color: #backgroundColor;
border-top: solid 1px (#backgroundColor - #292929);
}
This is an example from the official Bootstrap documentation.
And here is the code:
HTML
<footer class="footer">
<div class="container">
<p class="text-muted">Place sticky footer content here.</p>
</div>
</footer>
CSS
html {
position: relative;
min-height: 100%;
}
body {
/* Margin bottom by footer height */
margin-bottom: 60px;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
Considering this css:
.stickToBottom {
position: fixed;
bottom: 0;
}
You need to detect if vertical scroll is present using javascript :
function isVerticalScrollPresent() {
return document.documentElement.scrollHeight !== document.documentElement.clientHeight;
}
Then add "stickToBottom" class to the footer if this function returns false :
var footer = document.querySelector('footer');
if (!isVerticalScrollPresent()) {
footer.className += " stickToBottom";
}
You can ignore css code and set footer style with javascript.
Check this JsFiddle https://jsfiddle.net/LeoAref/9v0r7h9y/
HTML
<footer>Footer Content</footer>
CSS
html {
height: 100%;
}
body {
min-height: 100%;
padding-bottom: 25px;
}
footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: red;
color: #fff;
padding: 7px 0;
text-align: center;
}
You may need to use box-sizing: border-box; if you won't use bootstrap
<div id="first">Something</div>
<div id="last">something too</div>
<style>
#last {
position: absolute;
margin:0;
padding:0;
bottom:0; /*yes this div is at the bottom*/
}
#first {
}
</style>
My problem is that I can't reach last div with the border of the first div. I want last div to be at bottom and first div to have overflow:auto;? But it doesn't work. When I fill my div some text nothing is showing no scrollbar or anything like that and the first div kind of goes behind the last div even though I haven't assigned them any z-index values.
How Can I solve this? I want my first div to grow until it reaches last div and fill it with text maybe with scrolling appearing when it is only needed. I mean when two divs touch each other kind of.
This will give you a fixed size footer (#last) but the content (#first) expands as needed:
body {
margin: 0px;
padding: 0px;
}
#wrapper {
position: absolute;
top: 0;
bottom: 200px;
left: 0;
right: 0;
}
#first {
background-color: #5588FF;
width: 100%;
max-height: 100%;
overflow-y: auto;
}
#last {
background-color: #FF8855;
position: fixed;
bottom: 0px;
height: 200px;
width: 100%;
}
See this fiddle for the full solution: http://jsfiddle.net/xWa9f/4/
Is this what you want? Fiddle link: http://jsfiddle.net/emw2x/2/
body, html{
height: 100%;
}
#last {
margin:0;
padding:0;
bottom:0; /*yes this div is at the bottom*/
border: 1px solid black;
width: 100%;
height: 10%;
}
#first {
border: 1px solid red;
height: 90%;
width: 100%;
padding: 0;
margin: 0;
overflow: auto;
}
Give that a try to see if that's what you want.
if you accept some javascript in the mix, i have this solution for you.
first, change the absolute positioning to fixed positioning of the #last div.
set overflow:auto to the #first div and the javascript does the rest (you need jQuery):
(function () {
var heights = window.innerHeight;
var outerHeights = $("#last").outerHeight(true);
jQuery('#first').css('height', (heights - outerHeights) + "px");
})();
basically it calculates the window height of your monitor, it subtracts the height of the #last div and gives what's left to the #first div. when the content exceeds the available pixel height, a scroll bar will appear.
check it here: http://jsfiddle.net/vlrprbttst/rR7Uu/2/
the plus here is this works at any window resolution, so you don't have to worry about screen resolutions and you don't have to worry about the height of your #last div (margins, paddings, borders, whatever included)
I want to have the effect like dropbox:https://www.dropbox.com/ where my website is centered in the exact middle of the page.
Achieving this effect is way more complicated than it should be. Here's a bare-bones working example: http://jsfiddle.net/JakobJingleheimer/UEsYM/
html, body { height: 100%; } // needed for vertical centre
html { width: 100%; } // needed for horizontal centre
body {
display: table; // needed for vertical centre
margin: 0 auto; // needed for horizontal centre
width: 50%; // needed for horizontal centre
}
.main-container {
background-color: #eee;
display: table-cell; // needed for vertical centre
height: 100%; // needed for vertical centre
// overflow: auto; // <- probably a good idea
vertical-align: middle; // needed for vertical centre
width: 100%; // needed for horizontal centre
}
.container {
background-color: #ccc;
padding: 20px;
}
If you want to achieve this:
Here are different methods, with the pros/cons of each one, for centering a page vertically. Choose which one you prefer:
http://blog.themeforest.net/tutorials/vertical-centering-with-css/
EDIT. As suggested, I will proceed to explain one of the methods. It only works if you already know the height/width of the element to center (the link includes more methods). Assuming all your content is within <body>, and that your content is 900px x 600px, you can do in your css:
html {
width: 100%;
height: 100%;
}
body {
width: 900px;
height: 600px;
position: absolute;
top: 50%;
margin-top: -300px; /* Half of the height of your body */
}
However, this falls short for dynamically generated content, since you don't know the height of it. I've used it succesfully on log-in box pop-up and settings pop-up.
Another method I've used in the past for the whole page is the Method 1 from the link. It makes a set of divs to behave as a table, which can vertical-align to the middle.
If you want to align it vertically center, please check this web page: http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
If you know the width and height of your page
then wrap your contents in following div css
.center
{
position:absolute;
top:50%;
left:50%;
margin-left: -(yourPageWidth/2);
margin-top: -(YourPageHeight/2);
}
On your topmost div give margin:0 auto 0 auto; Also define some width to that div.
First create a main container of the desired width and then put all your code inside the main container. For Eg.
<body>
<div id="container">
......... your code
</div>
</body>
And in the css
#container{
width: 700px ;
margin-left: auto ;
margin-right: auto ;
}
You can change the width as per your needs
<body>
<div class="container">
......... your code
</div>
</body>
#container{
width: 700px ;
margin:0 auto ;
padding:0px;
}
Try this:
html
<span id="forceValign"></span><!--
--><div id="centerMiddleWrap">
<div id="centered">Hello this is some text. Hello this is some text. Hello this is some text.</div>
</div>
CSS
html {
height: 100%;
background: #eee;
}
body {
margin: 0;
height: 100%;
/*important*/
text-align: center;
}
#centerMiddleWrap {
/*important*/
display: inline-block;
vertical-align: middle;
}
#forceValign {
/*important*/
height: 100%;
display: inline-block;
vertical-align: middle;
}
#centered {
background: #000;
color: #fff;
font-size: 34px;
padding: 15px;
max-width: 50%;
/*important*/
display: inline-block;
}
Here is an demo
Wrap a div and define its width, use margin:0 auto for centering the div.
You can check a site's CSS by using Firebug or browser extensions.
I have a div , something like this
#footer
{ position:fixed;
left:40px;
top:0px;
}
The position is fixed when I scroll vertically or horizontally. But i want the div to be fixed when user scrolls the scroll bar vertically but should be varying when user scrolls the scroll-bar horizontally.
I have seen some of the forums and posts but mostly I found jquery script.I want to know if there is a way to do it in CSS?
Fixed position in only one direction
I read this post but I did not understand the jquery script. Kindly let me know the way to do it in css or the better way to do it with jquery.Thanks
Seems to be impossible to get this "look fine" with only CSS/HTML.
As mentioned from Ruup or Fixed position in only one direction, layering over JS for it, is a good option.
Fortunately, i found a way to get it work somehow (not that beautiful):
http://jsfiddle.net/MKEbW/5/
HTML (inside the body-tag):
<div id="simulated-html">
<div id="footer">
<span>
<!-- Footer text here -->
</span>
</div>
<div id="simulated-body">
<!-- Your website here -->
</div>
</div>
CSS:
* { margin:0; padding:0; }
html {
font: 12px/1.5em Georgia;
}
p { padding: 5px; }
html, body {
height: 100%;
overflow: hidden; /* hide scrollbars, we create our own */
}
#simulated-html {
background: orange;
overflow-x: scroll; /* force horizontal scrollbars (optional) */
overflow-y: hidden; /* hide. we use the #simulated-body for it. */
position: relative; /* to align #footer on #simulated-html */
height: 100%;
}
#simulated-body {
overflow-y: scroll; /* force vertical scrollbars (optional) */
overflow-x: hidden; /* hide. we use the #simulated-html for it. */
height: 100%;
background: #eee;
/* use as a container */
width: 450px;
margin: 0 auto;
}
#footer {
position: absolute;
bottom: 0px; /* vertical align it to #simulated-html */
width: 100%;
background: red;
z-index: 99; /* always show footer */
color: white;
}
#footer span {
width: 450px;
margin: 0 auto;
background: green;
display: block;
}
Seems to work in IE7+ and modern browsers, tested via browserlab.adobe.com.
Tested with scrollbars, smaller and wider viewports in Chrome 18.
I recommend a fallback for not capable browsers and/or a JS workaround.
The linked post is exactly what you need. You can copy the exact script.
$(window).scroll(function(){
$('#footer').css('left','-'+$(window).scrollLeft());
});
The div css is like this (probably not footer when it has top 0px :P but ok)
#footer
{ position:fixed;
left:40px;
top:0px;
}
When you scroll the jquery script just adjusts the left(x) coordinate to the same value as the scrollLeft of the window.
There is a small fix on the previous code.
The changed javascript code for moving fixed div horizontally
$(window).scroll(function(){
$('#footer').css('left',-$(window).scrollLeft());
});
how should the horizontal axis vary? the way this code is currently it would stay 40px from the left at all times. in order to make the left margin change position relative to the size of the window you must use percentages and negative margins. for instance, to center a fixed div:
#centered {
height: 350px;
top: 0;
position: fixed;
width: 1024px;
left: 50%;
margin-left: -512px;
z-index: 9999;
}
notice that your negative margin must be HALF the width of your div. if you want it 40px to the left of center then you would add another 40px to margin-left.