I'm trying to rewrite a site in proper HTML. The site I'm trying to replace was a complete mess. I've run into a problem where I can't get a <table> to fill the height of the <td> it's contained in. I've tried setting height: 100% on the <table>, which based on google and stackoverflow research should work, but I must be missing something stupid. I had tried to do the same thing with <divs> before switching to tables, but I'm not opposed to going back to <divs> if someone can suggest how to do it.
The content I'm developing is currently here: http://96.0.22.228/
Due to project time constraints, I've had to use bad hacks to get the pages looking correctly. I'm not declaring a <doctype> and I'm forcing IE to use IE7-quirks mode. I'd love to have recommendations on how to do this layout in a proper manner using HTML5 and CSS. It does not have to support older browsers, but it does have to look the same in the latest versions of Chrome, Firefox and IE. I'd also like to to do away with the images for the menus and style everything in CSS for the border frames and the menu text.
Even though I've had to complete the site as is, I'm open to going back and fixing it later if there's a good answer to this problem.
100% height in a table cell is always a pain. Technically speaking a TD has no height (because that depends on its contents). What you are asking the browser to do is make the child 100% of its parent, which is 100% of its child, which is 100% of its parent ... You can see how that might be a problem.
You could try adding an explicit height to the TD and using table-layout:fixed on the table. At least that way the browser knows the height of the parent without needing the height of the child but that still may not work.
You might need to rethink how you go about this.
The best solution for this is to have the parent element of the button have a height of 100% as well, assuming you want your button to have a height of 100%.
td {
height: 100%;
}
.btn {
width: 100%;
height: 100%;
}
<tr>
<td><button class="btn" id="1">1</button></td>
<td><button class="btn" id="2">2</button></td>
<td><button class="btn" id="3">3</button></td>
<td><button class="btn" id="plus">+</button></td>
<td rowspan="2"><button class="btn btn-block" id="equals">=</button></td>
</tr>
i got a one solution if you need your desired results you can adjust the padding of your (td.navigation a class link) through this you will get your results.
apply this css:-
td.navigation a {
color: #837768;
display: block;
font-size: 1.2em;
padding: 14px 5px;
text-align: center;
text-decoration: none;
}
So it's done here with divs, absolute positioning in %, and here's the part you won't like, with a specific height set in pixels. The trouble is, if you use table cells (td) the td's don't have height, and so any element inside will calculate 0 for 100% height.
When we use div's the problem is different. We can make sure they retain their height property, but there's no way to tell the div on the left, "be the same height as the div in the center." At least no way I know of. That being said, it seems like your flash object is the tallest thing, and you could easily set the height of all three div's at a pretty pixel perfect amount. Then stretch the ul navigation list to the height to 100% of the div it's nested within.
There's one other way to do this, that might meet your needs better, I'll detail it at the very bottom.
body,
html {
background: black;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#left {
position: absolute;
top: 10%;
left: 0;
background: #eeeeee;
width: 20%;
padding: 2%;
margin: 0;
}
#right {
position: absolute;
top: 10%;
left: 76%;
background: #eeeeee;
width: 20%;
padding: 2%;
margin: 0;
}
#center {
position: absolute;
top: 10%;
left: 24%;
background: #dddddd;
width: 48%;
padding: 2%;
margin: 0;
}
#flash {
background: red;
width: 500px;
height: 500px;
padding: 0;
margin: 0;
}
ul {
height: 500px;
padding: 0;
margin: 0;
padding-left: 25px;
background: #4359ac;
color: #ffffff;
}
li {
height: 10%;
padding: 0;
margin: 0;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>TheDavidFactor's Layout</title>
</head>
<body>
<div id="left">
<ul>
<li>Spa</li>
<li>Hotel</li>
<li>Activities</li>
<li>Hobbies</li>
<li>Night Life</li>
<li>Food</li>
<li>Feedback</li>
<li>Contact</li>
<li>About Us</li>
<li>Copyright</li>
</ul>
</div>
<div id="center">
<div id="flash">Here's your flash Object</div>
</div>
<div id="right">
here's the right div
<br>
<p>Let's throw some random text in here to take up space for now.</p>
</div>
</body>
</html>
The other option you have is to wrap the three columns in a container div, and define a height for that div, then stretch each of the columns to 100% height within that container div.
Related
I am creating a landing page with HTML/CSS and using a little bit of bootstrap. I am having trouble resizing my main page to fit 100% height and width when the page is opened.
I want it to look like google docs' main page: https://www.google.com/docs/about/. If you go there, you'll see:
the nav is in fixed position and follows you everywhere. I got that part down.
The main image automatically resizes depending on your screen size. The icon-arrow-hint (the arrow on mid-bottom of page) can always be seen on the bottom of the image.
Two problems that I have:
Got this weird gap on the right side even though I set right: 0.
After page load, it looks like it fits about 90% of the height and I still need to scroll down. I placed this text on the bottom - theoretically, this should be shown on the bottom of the screen without scrolling, but I have to always scroll slightly down.
This is the JSfiddle: https://jsfiddle.net/iggyfiddle/DTcHh/35435/
I am using position: absolute and I 0-ed all 4 sides.
How can I fit the yellow div 100% height and 100% width like the google page nicely?
If you give an element height: 100%, but there's another element above or below in the same container, you need to adjust for the height of the other element, otherwise there will be an overflow.
Also, adjust for the -15px horizontal margins applied by Bootstrap.
Try this:
.primary-content {
position: absolute;
top: 10%;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 90%; /* ADJUSTMENT */
background: yellow;
margin: 0; /* NEW */
}
https://jsfiddle.net/DTcHh/35437/
Your .primary-content div has the bootstrap .row class on it which declares negative horizontal margins. A solution would be to remove the .row class from your div or to override the margins in css.
These are the default bootstrap .row styles:
.row {
margin-right: -15px;
margin-left: -15px;
}
Using the class of .row adds a margin of 15px. A quick fix is to remove the class from primary-content div like so.
<div class="primary-content">
<div class="col-md-12">
<h1>This is a super awesome product</h1>
<h4>Help me stackoverflow, you are my only hope!</h4>
</div>
or add a class and remove the margins.
The reason that your yellow div is going too far is that you need to set the height to 90%.
To fix the weird padding on the right side, add margin: 0 !important;.
.primary-content {
position: absolute;
top: 10%;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 90%; // change this
background: yellow;
margin: 0 !important; // add this
}
See this JSFiddle or run the snippet below
/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
.universal-header {
background: red;
border-radius: none;
height: 10%;
width: 100%;
position: fixed;
}
.color-brown {
color: #58482C;
text-decoration: none;
}
.primary-content {
position: absolute;
top: 10%;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 90%;
background: yellow;
margin: 0 !important;
}
.bottom {
position: absolute;
bottom: 0;
right: 0;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<nav class="navbar universal-header navbar-static-top">
<a class="navbar-brand navigation-title color-brown">
</a>
<span class="color-brown navbar-brand navigation-title">HELLO</span>
<span class="navbar-brand navigation-title pull-right color-brown">Login</span>
<span class="navbar-brand navigation-title pull-right color-brown">Features</span>
<span class="navbar-brand navigation-title pull-right color-brown">About</span>
</nav>
<div class="row primary-content">
<div class="col-md-12">
<h1>This is a super awesome product</h1>
<h4>Help me stackoverflow, you are my only hope!</h4>
</div>
<div class="bottom">
You should be able to see me without scrolling
</div>
</div>
Problem 1:
Got this weird gap on the right side
When using bootstrap's row class it will add a margin of -15px to the left and right of your div, see the second answer to this question if you want to understand better why.
Solution: don't use the row class for your primary-content div.
Problem 2:
this should be shown on the bottom of the screen without scrolling,
but I have to always scroll slightly down
you are using absolute positioning, remember that needs a relative positioned parent container, in your case, since you don't have any, everything is relative to the initial containing block, hence your viewport/window.
Quick fix: delete the height: 100%; css from .primary-content
Warning: using absolute positioning the way you are right now will bring you trouble if you want to add more content below your yellow container
So I'm found an article on responsive design (here) and I tried to make something like what it had on part of the tutorial. The site said to divid the size of the element by the size of the container that the element(s) are in. (the reason I divided by 1000 and not 1050 is because the margins on the div#main make it 1000px even though the header is 1050px) If that doesn't make sense than the link can explain it. It looks fine with my browser at full size, but if I shrink the window to much then it doesn't resize the way it should. I'm not exactly sure what part of my code is wrong but if someone could help me that would be great! Here's a link to the page I made. And here is my source code:
<!DOCTYPE html>
<html>
<head>
<style>
body, html {
margin: 0;
height: 100%;
width: 100%;
}
header {
height: 100px;
max-width: 1050px;
margin: 0 auto;
}
#main {
border-radius: 25px;
background-color: #aaa;
height: inherit;
max-width: inherit;
margin: 25px;
}
.box {
width: 47.5%;
height: 75%;
margin: 1.25%;
background-color: #444;
border-radius: 15px;
float: left;
}
</style>
</head>
<body>
<header>
<div id="main">
<span class="box">
</span>
<span class="box">
</span>
</div>
</header>
</body>
</html>
Maybe if I explain what's happening you'll see that there actually is no problem.
The inner boxes have a fixed height based on 75% of the parent container's height. Therefore, the heights of all elements stay the same. However, your margins are fractions of the parent element's width, therefore they change with the page width. As the page gets smaller, the margin gets smaller. Since a div naturally lies as high on the page as it can, it moves toward the border of its parent.
All this is expected with your design. To fix it, set fixed top and bottom margins:
.box {margin: 12px 1.25%;}
I have a containing div that is NOT restricting the width of its child divs. The divs are stretching all the way to the full width of the screen, when i have a set width on both the container and the child. Why is this happening. I do NOT have any positioning or floating going on.
Please view my HTML:
<ul class="tabs_commentArea">
<li class="">Starstream</li>
<li class="">Comments</li>
</ul>
<div id="paneWrap">
<div class="panes_comments">
<div class="comments">member pane 1</div>
<div class="comments">member pane 2</div>
<div class="comments">member pane 3</div>
</div>
My CSS, the relevant parts of it at least:
#MembersColumnContainer {
width: 590px;
float: left;
padding-right: 0px;
clear: none;
padding-bottom: 20px;
padding-left: 2px;
}
ul.tabs_commentArea {
list-style:none;
margin-top: 2px !important;
padding:0;
border-bottom:0px solid #666;
height:30px;
}
ul.tabs_commentArea li {
text-indent:0;
margin: !important;
list-style-image:none !important;
padding-top: 0;
padding-right: 0;
padding-bottom: 0;
padding-left: 0;
float: right;
}
#paneWrap {
border: solid 3px #000000;
}
.panes_comments div {
display: ;
padding: px px;
/*border:medium solid #000000;*/
height:150px;
width: 588px;
background-color: #FFFF99;
}
You could set max-width on either, or both, of the div elements to prevent their expansion:
#containerDiv {
min-width: 400px; /* prevents the div being squashed by an 'extreme' page-resize */
width: 50%; /* defines the normal width of the div */
max-width: 700px; /* prevents the div expanding beyond 700px */
}
It might also be that you're allowing the div's overflowed contents to be visible, as opposed to hidden (or auto). But without specific examples of your mark-up and css it's very difficult to guess.
Generally giving elements layout is pretty straight forward (always assuming you have a good understanding of floating, positioning and the box model), and in most cases you wouldn't have to use max- min-width to control elements on the page.
My two cents: If I was you, I'd start stripping out code (starting with the !important rule), and see when the problem is solved. De-constructing the code like that is a good way to find bugs.
Sorry I couldn't help, but I'm reluctant to give advice since the code you provided shows a lot of other stuff going on elsewhere that might be contributing to your problem (like having to use !important).
:D
I figured out the problem. The file that was calling in the css was conflicting with another external css file that had the same element with the same name in it. Thank you all for your help though.
I am trying to get my right sidebar to fill to extend the full length of the content within my #wrapper on this site: http://www.starmedianetwork.com/
I put a red border around it to try to see where my #right is on my page. I have tried working with:
height:100% on that #right and others. Also searched on google about clear fixes but I couldn't get that too work, also came across some solutions on experts-exchange, but those didnt work.
Any ideas how I can get my sidebar to extend with the background-color to fit the length?
You could try this approach: http://www.alistapart.com/articles/multicolumnlayouts/
You can achieve this with a faux sidebar:
<div class="sidebar_back"><.div>
<div class="sidebar">
<p>The sidebar content</p>
</div>
With this css:
.sidebar_back {
top: 0;
left: 0;
bottom: 0;
z-index: -1;
width: 200px;
background: #444; // the color you want the sidebar to be
position: absolute;
}
.sidebar {
float: left;
width: 180px;
padding: 10px;
}
The .sidebar_back will extend all the way to the bottom of the page, so just give that the color that you'd like the sidebar to be, and the actual sidebar div will appear to be full-height. You can use a percentage-based width instead of pixels too. Here's a codepen showing an example:
http://codepen.io/poopsplat/full/jquBv
You cannot get a div to fill the height of it's parent. It may work in one browser, but I've had this problem and it is not simply solved by a height:100%.
You can simulate the background by creating a background that tiles all the way down the side. This isn't the most elegant solution.
The only other solution I have found is to use javascript. After the page loads, you can set the height of the div to precisely what it needs to be based upon the height of the div that you want it to expand within.
There may be some javascript libraries out there to assist you with positioning of this troublesome div, but I can't conjure up one at the moment.
I haven't tried this, but...it feels like it should work (which of course is likely the kiss of death to the attempt):
#wrapper
{position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
display: block;
width: 100%;
background-color: #ffa;
}
#right {position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 15%; /* this has to be fixed-size so you can account
for it in the next bit; but can still be kinda
fluid-ish... */
display: block;
background-color: #ccc;
overflow: auto;
}
#left {width: 83%; /* 100 - (15% + 2% (for a gutter)) */
margin-left: 1%;
margin-right: 16%; /* less than 100 - 83, to allow for rounding of % or px */
display: block;
background-color: #0ff;
overflow: auto;
}
p {display: block;
margin: 0.5em;
padding: 0.2em 0.5em;
}
...
<body>
<div id="wrapper">
<div id="left">
<p>The left-hand content</p>
</div>
<div id="right">
<p>The right-hand content</p>
</div>
</div>
</body>
It's not terribly pretty, but it does work. Though I'm not a fan of using position: absolute (or fixed) so if anyone's got a better suggestion I'd go for it =)
Incidentally, there's working demo of the implementation (with added 'lorem ipsum' goodness) over at: http://www.davidrhysthomas.co.uk/so/cols.html.
(Okay, I lied: I clearly have tried it now...)
Here is the way I have found to solve this issue:
You have to use four div tags - one main container which contains the sidebar, the main content, and a footer.
First, add and style the elements in your stylesheet:
#container {
width: 100%;
background: #FFFAF0;
}
.content {
width: 950px;
float: right;
padding: 10px;
background: #FFFAF0;
}
.sidebar {
width: 220px;
float: left;
padding: 5px;
background: #FFFAF0;
}
#footer {
clear:both;
background:#FFFAF0;
}
You can edit the different elements however you want to, just be sure you dont change the footer property "clear:both" - this is very important to leave in.
Then, simply set up your web page like this:
<div id=”container”>
<div class=”sidebar”></div>
<div class=”content”></div>
<div id=”footer”></div>
</div>
I wrote a more in-depth blog post about this at [http://blog.thelibzter.com/how-to-make-a-sidebar-extend-the-entire-height-of-its-container][1]. Please let me know if you have any questions. Hope this helps!
I solved my sidebar problem for my admin page using jQuery with just a couple of lines of code
$('aside').height($(window).height()-($('#header').height()+$('#secondary_bar').height())-2); // Extend sidebar to bottom of viewport
$(window).resize(function(){
$('aside').height($(window).height()-($('#header').height()+$('#secondary_bar').height())-2); //change size of bar when viewport height changes
$('#main').height($(window).height()-($('#header').height()+$('#secondary_bar').height())-2); //change size of main content when size of viewport changes
});
It seems to work in all browsers, however, when the content on the right is larger then the viewport and issue will occur when you scroll down. It can be fixed with some content height checks but for me it doesn't matter. Hope that helps someone out there =)
how could i vertically center a <div> within a <div> ?
my code so far:
<div style="height:322px;overflow:auto;">
<div style="border: Solid 1px #999999;padding:5px;">
</div>
</div>
i have tried "top:50%;" and "vertical-align:middle;" without success
EDIT: okay so it's been discussed a lot. and i've maybe started another mini flame war. but for argument sake, how would i do it with a table then? i've used css for everything else so far so it's not like i'm not trying to employ "good practices".
EDIT: the inner div does not have a fixed height
In short, you're stuffed. More on this in a recent question I asked Can you do this HTML layout without using tables? Basically the CSS fanatics need to get a grip and realize there's simply some things you can't do (or can't do well) without tables.
This anti-table hysteria is nothing short of ridiculous.
Table cells handle vertical centering really well and are backwards compatible as far as you could possibly care about. They also handle side-by-side content way better than floats, relative/absolute positioning or any of the other CSS type methods.
Joel coined (or at least popularized) the term "architect astronauts" in Don't Let Architecture Astronauts Scare You. Well, in that same vein I think the term "CSS Astronaut" (or "CSS Space Cadet") is equally appropriate.
CSS is an incredibly useful tool but it also has some pretty serious limitations. My favourite ishow numbered lists may only appear as "3." but not "3)" or "(3)" (at least prior to CSS3 generated content--or is it CSS2.1? Either way it's not widely supported). What an oversight.
But bigger than that is vertical centering and side-by-side layout. These two areas are still a huge problem for pure CSS. Another poster decided the relative positioning combined with negative margin heights was the way to go. How is that any better than:
<html>
<head>
<title>Layout</title>
<style type="text/css">
#outer { height: 200px; border: 1px solid black; width: 600px; background-color: #DDD; }
#inner { width: 150px; border: 1px solid red; background: yellow; margin: auto; line-height: 100%; }
</style>
</head>
<body>
<table>
<tr>
<td id="outer">
<div id="inner">Inner</div>
</td>
</tr>
</table>
</body>
</html>
which will work everywhere, everytime.
Here is an article on vertical centering in CSS. To achieve a similar thing they use three nested divs with relative+absolute+relative positioning just to get vertical centering. I'm sorry but whoever wrote that--and anyone who thinks that's a good diea--has simply lost the plot.
A counterargument is given in Tables vs CSS: CSS Trolls begone. The proof really is in the pudding. The vast majority of the top 20 (Alexa) sites still use tables for layout. With good reason.
So decide for yourself: do you want your site to work and spend less time getting it to work? Or do you want to be a CSS Astronaut?
It's non-trivial, there can be caveats, and it's not something CSS handles well at this point.
It is however quite widely discussed and googleable. This is a good example.
Whatever you do, please don't fallback to tables.
Edit: this is ridiculous, the following works perfectly well in a strict doc without resorting to table markup:
<style type="text/css">
.outer {height: 322px; overflow: hidden; position: relative;}
*|html .outer {display: table; position: static;}
.middle {position: absolute; top: 50%;}
*|html .middle {display: table-cell; vertical-align: middle; position: static;}
.inner {position: relative; top: -50%; overflow: auto;}
*|html .inner {position: static; max-height: 322px;}
</style>
<!--[if IE]>
<style>
.inner {height: expression(Math.min(this.scrollHeight,322)+'px'); width: 100%;} /* for explorer only */
</style>
<![endif]-->
<div class="outer">
<div class="middle">
<div class="inner">
Any text any height
</div>
</div>
</div>
I like this solution best. It is for IE8+, and is easy to understand.
<style>
/* Can be any width and height */
.block {
height:500px;
text-align: center;
}
/* The ghost, nudged to maintain perfect centering */
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can be any width or height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}
</style>
<div class="block"><div class="centered">Centered Content</div></div>
top: 50%; should work. you need to put margin-top to negative half of the height or it will start in the middle. Therefore, you need the height of the inner div. You also probably need position:relative;
Something like this for you inner div.
position:relative;
top: 50%;
height:80px;
margin-top: -40px; /*set to a negative number 1/2 of your height*/
Not very neat working with negative sizes (what does it even mean?) but maybe the easiest way.
<div style="display: table; height: 400px; #position: relative; overflow: hidden;">
<div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
<div style=" #position: relative; #top: -50%">
vertically centered
</div>
</div>
</div>
more information
Two techniques of many
Browser compatibility of the following has been tested in IE only. Modern browsers should handle these no problem.
#1 - Absolute and auto margin
Compatibility: IE 8 +
The combination of top, right, bottom, left and margin: auto centers the div vertically and horizontally.
The width and height are needed, but can be percentages
Can also be applied to an inner div with the parent set position: relative
Note: A max-width and max-height instead of a percentage height is possible IE 9 +. IE 8 requires a height.
html,
body {
height: 100%;
}
.outer {
background: #ff8f00;
height: 50%;
width: 50%;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<div class="outer"></div>
#2 - Flexbox
Compatibility: IE 11. See here for other browser support.
Using Flexbox and flexible vw and vh lengths
body {
margin: 0;
}
.outer {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.inner {
width: 50vw;
height: 50vh;
background: #ff8f00;
}
<div class="outer">
<div class="inner">
</div>
</div>
Do you absolutely need to do this with css? The above link looks pretty good, but you could get a result using javasctipt/jquery - determine the height of the innter div and adjust the margin.padding accordingly. Something similar to: (jquery)
var gap = ( $('the-outer-div').height() - $('the-inner-div').height() ) /2;
$('the-inner-div').css( "margin-top" , gap );
A table isn't necessary if you're willing to use the flexbox display model.
E.g.
<div style="height: 322px; width: 200px; display: flex; background: gray;">
<div style="border: Solid 1px #999999; padding:5px; margin: auto;">
This text would be both vertically AND horizontally centered, if it's inner height and width were less than the parent's height and width.
</div>
</div>
If you just want vertical centering use the rule "margin: auto 0;" in the child div.
p.s. You'll have to prefix your use of flexbox if you want cross-browser compatibility (e.g. "display: -webkit-flexbox;")
The display: flex property works especially well for centering, both vertically and horizontally. For vertical centering, add the properties display: flex and justify-content: center to the container.
Try line-height