I'm trying to tweak an existing app so would prefer to not change the dom structure. But I can't seem to get it how I need.
here is the example of where I am now.
https://codepen.io/m1nd/pen/QYLMeJ
<div class="canvas">
<div class="node node-1">node 1</div>
<div class="node node-2">node 2</div>
<div class="node node-3">node 3</div>
<div class="wrapper">
<div class="right-target"></div>
</div>
</div>
html, body {
height:100%;
background: yellow;
padding:0;
margin:0;
}
.canvas {
position:relative;
background: red;
height:100%;
overflow:auto;
}
.node {
position:absolute;
background: grey;
width: 200px;
height: 20px;
}
.node-1 {
top: 2px;
left: 2000px;
}
.wrapper {
position:relative;
height:100%;
background:pink;
}
.right-target {
position:absolute;
right:0px;
top:0px;
width:20px;
height: 100%;
background:green;
}
I want the .wrapper div to expand to the full width of the .canvas (scrolling) div, so the green .right-target should be to the far far right.But no matter what I try I can't seem to get the .wrapper div to expand past the viewport width.
I've seen examples that address this vertically (http://bennadel.github.io/JavaScript-Demos/demos/css-position-overflow/) but I can't seem to get the same principle to work in my case.
You have 2 options...
Make the .wrapper overflow the viewport by the exact width of its child element, which is what you actually want to out of the viewport, but this will be near impossible to do precisely (without some extremely new CSS features) becaaus you will have make that .wrapped element 100% + 20px wide (this is actually on the future specs I believe)
A better solution, if it works for your use case, would be having the green .right-target overlap is container (.wrapper) by its exact width...
.right-target {
...
right: -20px;
...
}
Sorry, misunderstood question. Revised answer below...
To do this you will need to use Javascript since the .canvas element is overflowing the viewport. You'll need to...
Calculate initial viewport width
Imperatively set the .canvas width to the viewport width + the offset of the element creating the overflow, .node-1 and 2000px respectively
On resize of the viewport you will have to re-calculate the new viewport.
reset the .canvas to the new viewport width + the same .node-1 offset
$(document).ready(function () {
var viewportStartWidth = window.outerWidth,
$target = $('.wrapper'),
$offsetElems = $('.canvas .node'),
offsetRight = (function () {
var largestOffset = 0;
$offsetElems.each(function(){
var pos = $(this).offset().left;
if (pos > largestOffset) {
largestOffset = pos;
}
});
return largestOffset;
})();
$target.width(viewportStartWidth + offsetRight)
$(window).on('resize', function(){
var viewportNewWidth= $(this).outerWidth;
$target.width(viewportNewWidth + offsetRight)
});
})
This makes you code very brittle though (if 2000px offset ever changes) and also has a significant performance cost (calculating and resetting width) every browser resize. You can improve this by debouncing/rate-limiting these calculations, but I would suggest a solution that does reorganize the DOM instead, even if you have to do it with JS on initial page load.
Full working example: https://codepen.io/anon/pen/QYWwKq
This is the only way you're able to do it with pure CSS, but take a look at the browser support to make sure it is acceptable for you...
.canvas {
...
width: calc(100% + 2000px);
...
}
Working example: https://codepen.io/anon/pen/GzRgeE
Related
I have a parent which has the CSS property of table-cell, with a child element that need to be 100% the height of the parent. I cannot get this to work in IE Edge - any ideas?
<div class="table">
<div class="table-row">
<div class="table-cell-1">
<a>need 100%!</a>
</div>
<div class="table-cell-2">
some content<br>
that is <br>
quite high
</div>
</div>
</div>
.table {
display:table;
}
.table-row {
display:table-row;
}
.table-cell-1, .table-cell-2 {
display:table-cell;
width:100px;
}
.table-cell-1 {
background-color:red;
}
.table-cell-2 {
background-color:green;
}
.table-cell-1 a {
display: inline-table;
background-color:#ccc;
height:100%;
min-height:100%;
}
See JS Fiddle: http://jsfiddle.net/82no4o0x/10/
You have this code:
.table-cell-1 a {
display: inline-table;
background-color:#ccc;
height:100%;
min-height:100%;
}
You're asking the a to be height: 100%. But 100% of what? There is no frame of reference. None of the parents have any height specified.
To see what I mean, make this adjustment to the parent:
.table-cell-1 {
background-color:red;
height: 100px; /* new */
}
Now it should work. See demo: http://jsfiddle.net/82no4o0x/23/
When using percentage heights in CSS you need to specify the height for all parent elements, up to and including body and the root element (html).
Read more here: Working with the CSS height property and percentage values
Because you haven't defined the table or the table row with a height, when you give the link a height of 100%, the link doesn't know what you want it to be 100% of. Although it looks pretty straight forward to you and me. So first of, try giving your table a fixed height and then making your cells height 100%... But I'm guessing you don't want to do that because you want it to grow or shrink depending on the content within it. I tried a few techniques using position absolute on the cell and positioning it relative to the row, but that didn't work in IE for some reason. So I came up with a bit of a trick/hack using a large top and bottom padding and a negative top and bottom margin.
.table-cell-1 { overflow:hidden }
.table-cell-1 a {
padding:2000px 0;
margin:-2000px 0;
}
https://jsfiddle.net/82no4o0x/24/embedded/result/
Currently I'm having troubles getting my layout working cross-browser. In the attached image you are able to see a preview.
height: 100%;
Some information:
div #Header
Width: 100%
height: variable
div #Sidebar (overflow-y)
Width: 300px
height: 100% minus header + footer heights
div #frameHeader
Width: 100% minus sidebar width (300px)
height: 100% minus header + footer heights
iframe #iframe (overflow-y)
Width: 100% minus sidebar width (300px)
height: 100% minus header + footer + frameheader height
div #Sticky Footer (sticky to bottom ofcourse)
Width: 100%
height: variable
I've spend countless hours trying to get this to work, I'm thinking someone should have faced this problem before? I'm hoping someone is able to give me a working cross-browser example!
Current code: http://jsfiddle.net/s6wVw/ (ugly css but I think you get the point ;))
Attachment (preview) can be found below
preview image
In your question you keep making false statements and contradicting yourself (e.g. you're talking about a sticky footer but you also imply that the page doesn't scroll - as heights of all elements sum to 100%). However, I'll try to help you none-the-less.
For the reason stated above, I've made the following assumptions:
You want the dimensions of the main areas (header, footer, sidebar, frame header, frame body) to always sum to 100%
You don't want the browser to scroll
You want scrolling in the side bar and frame body if the content overflows
The above would lead to a poor site design because if the browser/window size were to be <= 300px wide then you wouldn't be able to see any of the frame etc.. Similarly, if the browser/window height <= foot height + head height then you wouldn't see any of the sidebar, frame head, or frame body.
That being said, here is an example using jQuery, html, and css.
CSS
html, body{
margin:0; padding:0; border:0;
color:#fff;
}
#head{
width:100%;
background:#aaa;
}
#body{
width:100%;
}
#sidebar{
display:inline-block;
width:300px; height:100%;
background:#111;
vertical-align:top;
overflow:scroll;
}
#frame{
display:inline-block;
vertical-align:top;
height:100%;
}
#fhead{
width:100%;
background:#333;
}
#fbody{
width:100%;
background:#777;
overflow:scroll;
}
#foot{
position:fixed;
top:100%;
width:100%;
background:#aaa;
}
h1{margin:0; padding:10px;}
jQuery
function setSizes(){
var docWidth = $(window).width();
var docHeight = $(window).height();
var headHeight = $('#head').height();
var footHeight = $('#foot').height();
var bodyHeight = docHeight - headHeight - footHeight;
var fHeadHeight = $('#fhead').height();
$('#body').css({
height: bodyHeight
})
$('#sidebar').css({
height: bodyHeight
})
$('#frame').css({
width: docWidth - 300
})
$('#fbody').css({
height: bodyHeight - fHeadHeight
})
$('#foot').css({
"margin-top": -footHeight
})
}
$(function(){
setSizes();
var doit;
$(window).resize(function(){
setSizes();
setSizes();
})
})
HTML
<div id="head"><h1>Head Section</h1><br><br><br><br></div>
<div id="body">
<div id="sidebar"><h1>Side Bar</h1>
</div><div id="frame">
<div id="fhead"><h1>Frame Head</h1><br><br></div>
<div id="fbody"><h1>Frame Body</h1></div>
</div>
</div>
<div id="foot">
<h1>Foot Section</h1><br>
</div>
NOTES
You can put whatever content you like inside of the following divs: #head, #sidebar, #fhead, #fbody, #foot
The jQuery runs the setSizes(); function twice on window resize. This is to account for any scrollbars that may impact the available width/height
You may need to set additional overflow rules to other elements depending on what content you place in the divs
I want to create a header with 2 divs in it. The left div needs to be the same height as the right one, but the right one can scale based on its contents.
The left div's contents need to be vertically aligned to the middle.
I tried something like this:
<header>
<div id="test1">
<div>LOGO</div>
</div>
<div id="test2">
<h1>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</h1>
</div>
</header>
Use display: table-cell;
Working Demo
Edit:
In case if you want jQuery Solution it works on all browsers
You can fake this using overflow, padding and margins. It's completely cross browser compatible and doesn't need any JavaScript or anything. Just CSS. For example:
.header {
overflow: hidden;
}
.test {
background: red;
padding-bottom: 2000px;
margin-bottom: -2000px;
float: left;
width: 100px;
margin-right: 20px;
}
DEMO
There is also always faux cols (using a background image) but this is a better method that doesn't need images.
If you don't mind a bit of javascript:
$(document).ready(function() {
setHeight($('#test1'), $('#test2'));
// When the window is resized the height might
// change depending on content. So to be safe
// we rerun the function
$(window).on(resize, function() {
setHeight($('#test1'), $('#test2'));
});
});
// sets height of element 1 to equal the height of element 2
function setHeight(elem1, elem2) {
var height = elem2.height()
elem1.css('height', height);
}
DEMO
display: flex;
in the parent container works for me
Say, for example, I have two divs like so:
<body>
<div id="header">
MY CONTENTS
</div>
<div id="main">
MY OTHER CONTENTS
</div>
</body>
The first div has the attributes position:fixed; and width:100%; in CSS, the other div is just a div with much content inside.
Ok, there is a scrollbar in the right side, as usual. But this scrollbar affects all of the divs. I want the scrollbar to only affect the second div, is possible?
I tried everything with overflow:auto, overflow:hidden, and overflow:scroll but I didn't reach my goal...
EDIT: Here my jsfiddle: http://jsfiddle.net/upcfp/
Do you want to do something like that?
jsfiddle Example 1
I edited your jsfiddle and removed some of the not needed parts for your question:
edited version of your jsfiddle
seems like there was a
</div>
missing in the #header, but is that what you wanted to get?
Is this what you had in mind?
This is a simple method. I have the header at the top, absolutely positioned, at a height of 100 pixels. Below that, I have the main content area, which has a height of 100%, a transparent top border of 100 pixels (so the content appears below the absolutely positioned header).
The box-sizing property in CSS allows us to fit the entire element into the width and height we specify, including padding and borders. So including the top border, the height of the main content is 100%, and the scrollbar appears only on the main content div.
The trick here, by the way, is setting the height of both html and body to 100%. This wouldn't work otherwise.
CSS:
html,body {
height:100%;
}
#header {
position:absolute;
width: 100%;
height: 100px;
background:#c3c3c3;
z-index:1;
}
#main {
background: #eee;
height:100%;
border-top:100px solid transparent;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
overflow:auto;
}
Here is your fiddle using my solution.
Try:
#div2 {
overflow-y: scroll;
}
That will only put the scrollbars when needed. To always display them use overflow-y: scroll;. I had prefixed the second div's ID with div as you should not use only numbers for IDs or attributes in general.
The # signifies that the rule will apply to an element with the ID that follows the #. If you wanted it applied to all div then you would use a class instead.
Demo: http://jsfiddle.net/6EVtN/
Without seeing more code, the issue could be due to browser compatibility. Example above was tested in Mozilla Firefox 13.0.1 and IE 8.
Updated Demo: http://jsfiddle.net/j4uAM/
Ok, I solved my problem, I used this code:
body{
overflow: hidden;
}
#main{
overflow: scroll;
}
#maincontent{
height: 1500px;
}
I specified the height in content of #main and it just worked, thanks to everybody!
This a perfect solution, but I don't know how to keep code format in stackoverflow:
<script>
$("#cart").bind("mousewheel", function(e){
var intElemScrollHeight = document.getElementById("cart").scrollHeight;
var intElemClientHeight = document.getElementById("cart").clientHeight;
if( intElemScrollHeight - $("#cart").scrollTop() === intElemClientHeight) {
$(document).bind("mousewheel", function(event) {
event.preventDefault();
});
}
if(e.originalEvent.wheelDelta /120 > 0 ) {
if($("#cart").scrollTop() != 0) {
$(document).unbind("mousewheel");
} else {
event.preventDefault();
}
}});
$("#cart").on("mouseleave", function(event) {
$(document).unbind("mousewheel");
});
</script>
im trying to get some background images around a content div. Thing is, the content div should have a flexible width (no problem). The background pics should always be left and right attached to the content div. BUT: the horizontal scrollbar should only be triggered, when the user reduces the window to the width of the content div.
Picture: Structure
I came up with something like this:
<div>
<div class="header">/div>
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
<div class="content">Content</div>
</div>
<div class="footer">/div>
</div>
.wrapper{
margin:auto;
width:950px;
position:relative;
}
.left {
background:transparent url(../images/left.png) no-repeat scroll 0 0;
position:absolute;
top:0;
left:-120px;
width:120px;
height:500px;
}
.right {
background:transparent url(../images/right.png) no-repeat scroll 0 0;
position:absolute;
top:0;
right:-120px;
width:120px;
height:500px;
}
Scrollbars always appear when window hits the right absolute div. I need them to be two divs (left/right) because the content div should be flexible and not hide the background when it extends to much.
Someone got a tecnique for this?
you have an unnamed plain root container div.
Add this style for that div (or give a class/id name to wire css deceleration).
Main point is min-width... Keep it same with your container div's width.
also adding body,html{margin:0;padding:0;} will be nicer.
style="width:100%;overflow:hidden;min-width:950px;position:relative; height:100px;"
this will work fine exept for ie6.
For ie, you can apply some js magic.
Let's assume you're using jquery library and you gave id name "shell" to your root container div.
Then try this script only for ie6. (create exclusion or something like that):
$(document).ready(function(){
$('#shell').each(function(){
var that = this;
var contentWidth = 950;
check();
$(window).resize(check);
function check() {
var winWidth = Math.ceil($('body').width());
if(winWidth <= contentWidth) {
$(that).css({'width':contentWidth});
} else {
$(that).css({'width':'100%'});
}
}
});
});
This script will make "shell"s width 100%. (if browser's width is larger than 950px) otherwise it'll lock shell's width with 950px and that will enable scrollbar.
I did something similar for a website, the solution I came with was this:
I created an image with the left and right content on the background and the space of the content in the middle to just be a solid color, even though the image is 1400 x 539 it weights 12 KB, so it's pretty good.
<html>
<body>
<div id="wrapper"></div>
</body>
</html>
body {
background: #fff url(left-and-right.jpg) no-repeat center top;
text-align: center;
}
#wrapper {
margin: auto;
text-align: left;
width: 960px;
}