Popping out of containing element and extending to rest of screen - html

I have a div, well, 2 div's and when I hover over the "main" div, I want the hidden div to appear (located inside the main div) and then pop its bottom out to stretch to fill the remainder of the bottom half of the screen.
An example would be:
I'm not asking for anyone to write code for me. I would very much appreciate any links/resources you might have that could point me in the right direction. I've been at this for hours, and I don't want to have a completely broken-up layout just to achieve this effect, but I'm just not able to get it.
I have tried this and many variations of it with no success:
HTML:
<div id="main">
<div id="hiddendiv">
</div>
</div>
CSS:
#main{
width: 150px; height: 75px;
background-color: #0061cc;
}
#hiddendiv{
visibility: hidden;
width: 75px; height: 100%;
background-color: lightgray;
}
#main:hover > #hiddendiv {
position: relative;
height: 100%;
visibility: visible;
}

Well, I've got some good news and some dumb news.
The dumb news is that for all intent and purpose, it's approximately 137% impossible to use nothing but CSS to specify that an object take up "the rest of the height", without using some sort of hard-coding, even if that hard-coding is in percentages.
Even using what was supposed to be the magic bullet ( calc() ) in CSS wouldn't be guaranteed to work, because you can't necessarily do a calc which says "based on the current scroll-position, and the relative position of the top-edge of my parent, and the remaining pixels to the bottom of the screen, set my height to THAT".
Any CSS-only solution that I gave you would fall short by:
only stretching to 100% of the parent's height
stretching to 100% of the page's height (including going up)
would require a guarantee that your parent isn't going to move up or down, at all (no scrolling), or that when the pop-out comes, the user won't be able to scroll until the pop-out goes away (or would look at home if the pop-out stayed stuck on-screen, in the same spot while a user scrolled up or down)
There's the bad news.
The good news is that this isn't a particularly difficult fix in JavaScript.
You'd want to use getBoundingClientRect on the pop-out, and use the .top property of the returned object, to figure out what your top edge is.
Then you could use your document.body.scrollTop and window.screen.height to figure out where you are, in relation.
ie: childEl.getBoundingClientRect().top - document.body.scrollTop should equal where you are onscreen. Subtract that from window.screen.height and now you know how tall you need to be to hit the current bottom-edge (which could still be scrolled past).
This is not a bulletproof, cross-browser solution.
But it's a starting point.
Also, I'd suggest that you use display:none, rather than visibility:hidden. The difference is that if you set the child to be width:200% it's going to give you a big, ugly scrollbar off the side of the page, even though it's invisible. visibility:hidden still pushes stuff, even if it's just pushing the edge of the page off to the side.
display:none hides the stuff, but also stops pushing everything.
Sort of like the difference between The Invisible Man and a ghost, trying to squeeze onto a packed subway car.

I think you are looking for this....
HTML
<div id="main">
<div id="hiddendiv">
</div>
</div>
CSS
#main{
width: 150px; height: 75px;
background-color: #0061cc;
}
#hiddendiv{
visibility: hidden;
width: 150px; height: 100%;
opacity: .7;
background-color: lightgray;
}
#main:hover > #hiddendiv {
position: absolute;
height: 98.5%;
visibility: visible;
left:260px;
}
#main:hover
{
width:400px;
}
DEMO
I hope this may help you.....

After a few more attempts using JSFiddle, I am finally satisfied with the result.
HTML:
<div id="main">
<div id="hiddendiv">
</div>
</div>
CSS:
#main{
width: 150px; height: 75px;
background-color: #0061cc;
}
#hiddendiv{
visibility: hidden;
width: 75px; height: 100%;
opacity: .7;
background-color: lightgray;
}
#main:hover > #hiddendiv {
position: absolute;
height: 98.5%;
visibility: visible;
}

Related

How to add shapes/decoration correctly to the page layout

I know it might be a duplicated question, but I couldn't find the answer anywhere else in the internet.
Question is very simple: I want to know how should/could I add shapes/decoration to the page layout correctly so it will not look broken inside a responsive container.
Click here to see the picture!
Actually I don't know the way to add that much shapes without making some mess in the code or completely braking the responsiveness of the container itself. If anybody already have done this, please describe your solution/method of doing this correctly. Thank you in advance and hope this will be useful to somebody else.
You should probably set a position : relative in the parent element and then use position: absolut; with relative unites.
Also take care to have a lower z-index for the decorations:
section {
background-color: rgb(69, 83, 95);
display: inline-block;
position: relative;
width: 70vw;
height: 70vh;
}
.content {
z-index: 2;
}
.element {
position: absolute;
z-index: 1;
color: white;
}
.element1 {
top: 20%;
left: 20%;
}
.element2 {
top: 80%;
left: 30%;
}
.element3 {
top: 50%;
left: 70%;
}
<section>
<span class="element element1">+</span>
<span class="element element2">*</span>
<span class="element element3">*</span>
</section>
As the decorations are just that, with no particular meaning that for example would be read out by a screen reader, I would put them in as background images - either as SVGs or gradients (if suitable) and position and size each one in terms of %s relative to the dimensions of the main element.
That way you have a responsive page and you haven't cluttered up the HTML with elements.
Each of the decorations seems separate, but if they overlap then remember the one that comes first in the background-image list will be shown on top of one coming afterwards.
So you are going to end up with CSS looking something like this:
background-image: url(svg1), url(svg2), url(svg3)...;
background-position: x1% y1%, x2% y2%, x3% y3%,...;
background-repeat: no-repeat no-repeat;
background-size: w1% h1%, w2% h2%, w3% h3%,...;
It's easy to work out the percentages, just use a ruler on the image - any units will do, and divide by the width or height of the main element as appropriate * 100.

How do I make element keep hover ability but make clicks go through it?

I'm trying to make a box which expands into four boxes (which are also links) when you hover over it. To do this I have 5 boxes. One which acts as the parent box and contains all others, one which expands on hover, and the other three which are in the second one positioned to opposite corners. My problem is that the second box has to be over the others for the hover to work but then the user can't click the buttons below it.
Here's an abbreviated version (CSS then HTML):
#sidebar {
height: 100px;
width: 100px;
position: relative
}
#sidebar #container {
height: 100px;
width: 100px;
transition: all 2s;
}
#sidebar #container:hover {
height: 200px;
width: 200px;
}
#sidebar #container #button1 {
height: 100px;
width: 100px;
position: absolute;
right: 0;
z-index: -1;
}
/* Repeat with two buttons positioned to bottom corners */
<div id="sidebar">
<div id="container">
<div id="button1"></div>
<!-- Repeat buttons again -->
</div>
</div>
I'd rather not use anything but CSS and HTML, but if it's the only way I'll be open to it. Jsfiddle here.
EDIT: I fixed the jsfiddle with idrumgood's solution.
It's your negative z-index that's causing the issue. That places it behind everything else.
You need to add this style to your links:
a{
display:inline-block;
}
And adjust the size of the second link. Try it and tell me! :)
You can add the hover effect to your sidebar instead and changing the visibility of your buttons,as well as removing z-indexes http://jsfiddle.net/4zLjas39/12/
#container a div{visibility:hidden;}
#sidebar:hover #container a div{visibility:visible;}
You can allow clicks to pass through an element by setting it's css pointer-events to none
#the_invisible_object{
pointer-events: none;
}

"Sticky" sidebar overflowing vertically

We have a sticky side panel on our page implemented with the following very-simple CSS:
position: fixed;
top:62px;
bottom:10px;
Where the top and bottom properties create the desired margins.
The problem is that this panel contains several accordion-style elements, and expanding some of them causes the content to overflow past the bottom of the screen and become invisible/inaccessible. Adding an overflow:auto; rule to the above css style almost solves the problem, by inserting a scrollbar that allows the user to scroll vertically to see the would-be hidden content. However, this results in two scrollbars - one for the main nav and one for the sidebar - which feels clunky an unintuitive. Instead, I'd like to have the "fixed" element scroll with the main scrollbar when it overflows. I'm aware that this would essentially make it not a fixed element, and thus am afraid I'll have to resort to JS to make this happen - but does anyone have a cleaner, html/css-only way of handling this?
I'm not sure this is what you need, but hope it helps some way.
#container1 {
height: 400px;
width: 200px;
overflow: hidden;
position: fixed;
top: 62px;
bottom: 10px;
background: #888;
}
#container2 {
width: 100%;
height: 99%;
overflow: auto;
padding-right: 20px; /*Adjust this for cross-browser compatibility */
}
#container2 ul li {
height: 300px;
}
html, body {
height: 99%;
overflow:hidden;
}
<div id="container1">
<div id="container2">
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
</div>
<div>
JSFiddle
Also in chrome you can try out:
::-webkit-scrollbar {
display: none;
}
But this snippet works only in chrome, so I would rather use the above.
Let me try to help. Use Panel-body class selector to handle this.
First you should do many things, such as, width of the div and the second div.
You can manage to hide the scrollbar as follows:
.panel-body {
height:300px;
overflow:auto;
margin-right:0px; // when it shows scrollbar, you need to set it MINUS.
}
Second, you also take notice when browser window gets resized by user and you need to manage Media Queries in related to the div width.
This is the DEMO.

min-height not working as expected

Given the following structure, I need level2 have a min-height without changing the structure. Further, I am not able to move the overflow: hidden to a different class (the example is simplified, it would affect a lot of other things). It works with px, but not with %. All other css properties can be changed.
I am aware of vh, which works exactly like it should. But I would love a solution with CSS2.
Fiddle
HTML:
<div id="level1">
<div id="level2">
<div id="heighter"></div>
</div>
</div>
body and html: height 100%
level 1: min-height 100%, overflow hidden
level 2: min-height 100%
heighter: height 200px
Edit: More informations about the overflow:hidden
I am using this for a offcanvas navigation. This is a place where I can't use max-width (right?). If I replace the overflow with the max-width, the layout gets recalculated and after that I am able to scroll the level2 on the x-axis (left and right). Same problem as here (click on Push-Menu-Left and then you are able to scroll the x-axis). What I am trying right now is preventing the x-axis scrolling and being able to use the min-height: 100% corretly.
In order to calculate min-height, div#level2 needs to refer to the height definition of its parent. In your code, div#level1 does not have a specified height. You an specify one like so:
#level1 {
height:100%;
overflow: hidden; /* This has to be here */
background-color: red;
}
WORKING EXAMPLE
EDIT:
Explicitly setting height on div#level1 (rather than setting min-height), you no longer need the overflow:hidden definition. Removing that allows the page to scroll when div#heighter expands beyond the browser's height.
(You mentioned that you need the overflow:hidden for other reasons. If possible, please edit your question to describe those reasons a bit more.)
#level1 {
height:100%;
background-color: red;
}
#level2 {
min-height: 100%;
background-color: lightseagreen;
}
#heighter {
height: 2000px;
width: 100px;
background-color: white;
border: 5px dashed black;
}
WORKING EXAMPLE
http://jsfiddle.net/b8uj75e5/3/
#level2 {
min-height: 1000px; /* Working */
min-height: 100%; /* Not working */
background-color: lightseagreen;
display: block;
position: absolute;
width: 100%;
}
IT LIVES.
I just messed around until it worked.

Why doesn't my display: table-cell element fill available space?

Update - I've decided against the JavaScript solution. The only way to make sure it always works is to put it in setInterval() going every few seconds. Don't want to do that. I know this CSS is possible, I've seen it work. I'll re-open the bounty for more like 150 if it ends.
I have a modal popup made up of two sections: left and right. Within both sections are a label above and the content below. The label is fixed at a certain number of pixels, but the bottom area needs to be able to fill the remaining space, so I'm using display:table on the left and right sides and display: table-cell on the inner sections to achieve the "fill remaining space" effect. It works great in Chrome and Safari.
Here's the CSS:
#tagBoxLeft,#tagBoxRight {
display: table;
height: 100%;
width: 50%;
position: absolute;
right: 0;
opacity: 0;
}
#tagBoxLeft { left: 0 }
#tagBoxDescription {
display: table-row;
-webkit-border-top-left-radius: 20px;
width: 100%;
word-break: break-all;
word-wrap: break-word;
-webkit-box-shadow: 0 1px 0 #FFF;
-moz-box-shadow: 0 1px 0 #FFF;
box-shadow: 0 1px 0 #FFF;
}
.nano {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
display: table-cell;
}
#taglabel {
display: table-row;
z-index: 10000;
border-top: 1px solid #FFF;
width: 100%;
height: 39px;
}
And it just makes a bunch of divs into a table so they can have heights that are relative to each other. Also notice that the left and right sides are relative to the browser window, so that's why I can't just use percentages.
However, in Firefox and Opera, the #tagBoxLeft and #tagBoxRight sides sections refuse to accept height:100%; while they have display:table;. So it won't force the bottom sections up responsively.I know Firefox & Opera support this normally (see http://jsfiddle.net/Qxswa/). But why does all my content overflow in Firefox and Opera?
Here's a screenshot of the issue:
Is there a reason why you can't simply use JavaScript to calculate the correct height and apply it inline? It's not as nice and simple, but it would be trivial for what you are describing.
var boxHeight = $('#tagBox').height();
var leftLabelHeight = $('#tagBoxDescription').height();
$('#tagBoxPopular').css('height', boxHeight - leftLabelHeight + 'px');
var rightLabelHeight = $('#taglabel').height();
$('#tagBoxStream').css('height', boxHeight - rightLabelHeight + 'px');
Here's an alternative to using display:table and friends, which uses the oft-neglected ability of absolutely positioned elements to have both their top and bottom (and left and right) values set. It essentially 'sticks' the top and bottom edge, giving you a height relative to a container, but without explicitly setting a height.
UDPATED: As Jackson mentioned, the CSS-only version of this code doesn't provide an auto-height, fixed panel in the column. A simple bit of JS will fix that - you'd just need to set a sensible default height for users without JS. The JS only needs to run when you load the modal, not at intervals.
Here's the updated fiddle: http://jsfiddle.net/cxY7D/5
and here's the simplified HTML:
<div id="modal">
<div class="left">
<div class="description">
<h1>#tag_name</h1>
<dl>
<dt>Tags</dt> <dd>27</dd>
</dl>
</div>
<div class="contents">
<div class="header">
<h2>Featured</h2>
</div>
<ol>
<li>Something Something</li>
<li>...</li>
</ol>
</div>
</div>
<div class="right">
<div class="contents">
<div class="header">
<h2>Recent</h2>
</div>
<ol>
<li>Something Something</li>
<li>...</li>
</ol>
</div>
</div>
</div>
and CSS:
body {
background:#444;
}
#modal {
background:#FFF;
position: absolute;
top: 4em;
bottom: 4em;
left: 6em;
right: 6em;
}
#modal .left,
#modal .right {
position:absolute;
top: 0;
bottom: 0;
}
#modal .left {
background:#ACF9E4;
left: 0;
right:50%;
}
#modal .right {
background:#FCFFCD;
right: 0;
left:50%;
}
#modal .contents {
position:absolute;
top: 0;
bottom: 0;
width: 100%;
overflow-y:auto;
}
#modal .description {
height: 8em;
}
#modal .description + .contents {
top: 10em;
}
#modal .header,
#modal .description,
.contents li {
border-bottom:1px solid #CCC;
padding: 1em;
}
#modal .description dt {
float: left;
padding-right: 1em;
}
It's a really useful and robust technique. A lot of people get the shudders when you mention 'absolute positions', but used like this, it's really liberating!
The JS (assuming jQuery)
$(function(){
$('#modal').on('display', function(){
//Calculate the height of the top left panel, and provide the remaining space to the bottom left
var leftColumn = $(this).find('.left'),
descriptionHeight = leftColumn.find('.description').height('auto').outerHeight(); //Set the height to auto, then read it
leftColumn.find('.contents').css('top', descriptionHeight)//Apply the height to the scrolling contents pane
});
$('#modal').trigger('display');
});​
The JS resets the top-left pane to auto-height, then reads the height and applies it as the top co-ordinate of the bottom-left panel. It's applied as a custom event, so you can trigger it as part of your modal display code.
Here's an answer I gave, using a similar technique, and more explanations of the hows and whys: The Impossible Layout?. Check the A list apart article for more discussion, and some simple fixes that make it work in IE6 (if you care about that).
I open your site on firefox and the hashtag links i see with chrome are gone. Are you doing some fix-attempts right now? If you put the links back in for the ff version I can help you debug this.
UPDATE:
What I see is a highly overcomplicated mix of display:table's and display:table-cells's with absolute and static positionings combined with percentual heights and many other highly cross-browser volatile mixes.
Doing lots of patching and fixing I was able to get this:
There's obviously many errors still present but at least you get some scrollbars.
Basically, the problem is that you're relying upon percentual heights and shady table-displays that are seemingly not very evenly rendered by different browsers.
We have two options here:
1.- Keep your original css/html approach and troubleshoot the JS scrollbar.
2.- Go for a much much much simpler css/html variant
Cheers
G
You may want to look at how you're using <section>. It is not the same as a <div>.
W3C - Using HTML5 section elements , and header elements.
<header> appears the same. They're both flow elements, and not designed as content containers, but as semantic structuring elements for content containers.
I used Firebug and changed both <header> and <section> to display:block on a hunch. Things started to shape up; however I could not get the scroll effect to fire after those changes. I then changed <header> in safari to display:inline. Sure enough - both my browser windows looked like this:
You need to have the #tagboxleft and #tagboxright's overflow hidden. This can be done by setting #tagbox to overflow:hidden, however that will hide part of the close button. so you need another div wrapped around the left and right but not the x with overflow:hidden.
Like so:
<div id="tagbox">
<div id="tagboxX"></div>
<div id="tagboxleftright" style="overflow:hidden"> <!-- This is the wrapper div around tagbox left & right. Of course, move overflow:hidden to the style sheet -->
<div id="tagboxLeft"></div>
<div id="tagboxRight"></div>
</div>
</div>
This worked in Firefox and it should work in Internet Explorer.