How can I get a div to fill a table cell vertically? - html

As a followup to this question on absolute positioning within a table cell, I'm trying to get something working in Firefox. Once again, I'm about 95% there, and there's just 1 little thing that's keeping me from declaring victory. Using the follow sample markup:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Test</title>
<style type="text/css">
table { width:500px; border-collapse:collapse}
th, td { border:1px solid black; vertical-align: top; }
th { width:100px; }
td { background:#ccc; }
.wrap { position:relative; height:100%; padding-bottom:1em; background:#aaa; }
.manage { text-align:right; position:absolute; bottom:0; right:0; }
p{ margin: 0 0 5px 0; }
</style>
</head>
<body >
<table>
<tr>
<th>Mauris tortor nulla, sagittis ut, faucibus eu, imperdiet ut, libero.</th>
<td><div class="wrap"><p>Cras diam.</p><div class="manage">Edit | Delete</div></div></td>
</tr>
<tr>
<th>Cras diam.</th>
<td><div class="wrap"><p>Cras diam.</p><div class="manage">Edit | Delete</div></div></td>
</tr>
<tr>
<th>Cras diam.</th>
<td><div class="wrap"><p>Mauris tortor nulla, sagittis ut, faucibus eu, imperdiet ut, libero. Sed elementum. Praesent porta, tellus ut dictum ullamcorper, est ante condimentum metus, non molestie lorem turpis in sapien. Aenean id enim. Nullam placerat blandit ante. Aenean ac ligula.</p><div class="manage">Edit | Delete</div></div></td>
</tr>
</table>
</body>
</html>
How can I get the wrap div to always fill the cell, so that the management area sits at the bottom of the cell? And yes, the data that I am putting in the table is (in my mind) tabular, so I would like to use a table here. As a last resort, I may turn to an ugly nested div solution, but since a table is semantically correct here I'd like to use one if possible. Note that the background colors are simply to show the relative sizes of the elements - I don't care about background for my layout. Also note that I'd like the cells to have a flexible height, so that they only expand enough to fit their content.

You could put (the same) fixed height on the table cell & wrap div thusly:
<style type="text/css">
table { width:500px; border-collapse:collapse}
th, td { height:200px; border:1px solid black; vertical-align: top; }
th { width:100px; }
td { background:#ccc; }
.wrap { position:relative; height:200px; padding-bottom:1em; background:#aaa; }
.manage { text-align:right; position:absolute; bottom:0; right:0; }
p{ margin: 0 0 5px 0; }
</style>

Are you just trying to get the backrground to match the same colour? and not alignment, then you can use a background image in css to give the same effect, cos FF does not render the element to 100% inside a container. If the container is set on auto height, then the child will be set to auto too. The makes the rendering faster.
So the best bet would be a css background image.

Related

How to "left-align" a table in the "center" of the page?

This may be a weird one:
I have a page where I don't control the HTML, but I can inject some additional CSS.
I have some tables which I need to align on the page. The problem is that all the other elements are aligned center on the page, but they all have fixed width. For aesthetic reasons I don't want all the tables to be of the same width, I want them to be of variable width depending on the contents.
Notice in the below code how the main container is full width on the page and the other content does not have any other wrapper elements around them. Because of this, all individual items are centered on the page using css. And also because the main container has other full width children (that I have not shown here), I cannot make the container be of reduced width and center it.
*, *:before, *:after {
box-sizing: border-box;
}
.content {
width: 100%;
background-color: #ddd;
}
.content p,
.content span,
.content table {
display: block;
max-width: 300px;
margin-left: auto;
margin-right: auto;
background: #999;
}
<div class=content>
<span>Some content header </span>
<p>Some content which can be long.. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ac blandit nisi. Curabitur fermentum dui tortor, sed rutrum velit facilisis non. Aliquam erat volutpat. Phasellus egestas erat sapien, ac scelerisque erat rhoncus id. Nullam aliquam libero et aliquam bibendum. Curabitur porttitor lorem in libero molestie, vitae ornare lacus fermentum. Curabitur condimentum tellus fermentum, feugiat nunc dictum, commodo est.</p>
<table class=table1>
<tr>
<td>Test Table 1</td>
</tr>
</table>
<br/>
<table class=table2>
<tr>
<td>Test table 2 which need to have more width than the first one</td>
</tr>
</table>
</div>
What I finally want looks something like this image:
Notice that:
The tables are left aligned with the rest of the items in the page.
The tables are of different width.
Obviously I don't want to hardcode the widths or the left margin for the tables.
Any idea if I can achieve this using just CSS?
Add the following CSS to an outer wrapper on your table:
.wrapper {
display: block;
margin: auto;
max-width: 80%;
}
Add this CSS to your table:
table th, table td {
text-align: left;
}
The CSS above will both center your table to 80% of the screen width as well as left align all text within it.
Update
If you cannot center the wrapper element, use flexbox on the wrapper element instead to center all of the children.
.wrapper {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
The CSS above makes it so that any element that is a direct child of the wrapper will be centered, so all elements will be equally centered, including your table. If you want them equally spaced between each other, change justify-content: center; to justify-content: space-between;.

Elements don't reposition when browser is resized

I'm rying to create a website with only horizontal scrolling. Please take a look at this demo. My problem is when I resize the browser, the content(the paragraph inside the light yellow box) doesn't reposition. I want that paragraph to be positioned above the yellow ring segment. How can I do that?
Below is my code.
HTML
<html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/styles.css" />
<script type="text/javascript" src="scripts/jquery.min.js"></script>
<script type="text/javascript" src="scripts/scripts.js"></script>
</head>
<body>
<div id="container">
<img id="backimage" src="images/rings.png" />
<div id="info">
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at sollicitudin turpis. Fusce fermentum, odio vitae luctus mollis, tortor mauris condimentum leo, at interdum urna massa a orci. Class aptent taciti sociosqu ad litora torquent per conubia
</p>
</div><!-- end of info -->
</div><!-- end of container -->
</body>
</html>
CSS
a { text-decoration:none; }
li {list-style-type:none; }
body { overflow-y:hidden; }
#container {
position:absolute;
height:100%;
width:10000px;
background-color:#FC9;
}
#info {
position:absolute;
width:200px;
height:220px;
background-color:#FFC;
top:180px;
left:250px;
}
#backimage {
position:absolute;
height:100%;
background-size:cover;
bottom:0;
}
I tried setting #info's position as relative but when I do that, it disappears from the page.
what would you like to happen with the content? cause with the current parameters it doesnt matter if the position is relative or absolute, it will stay 180px down and 250px in from backimage upper left corner... also its size won't change.
You are defining every position as absolute. This is not a good solution. Instead you should use relative layouts. They may be a bit more complicated and not as "free", but they do solve most of the problems. Delete backImage and container from you HTML and do something like this:
a { text-decoration:none; }
li {list-style-type:none; }
body {
overflow-y:hidden;
background:url(images/rings.png);
background-color:#FC9;
}
#container { //body is the container. You dont need something like this in this case.
}
#info {
background-color:#FFC;
//width and height are dynamic to the size of content
margin-top:180px; //You just set the margin (outer gap) instead of the position.
margin-left:250px;
}
#backimage { //You don't need a back-image if you use background:url(...) in body
}
If you want the outer gap of the box to get smaller if window is smaller use percentages with margin.
If you want to limit the size of information div use max-width:xyz;
As I read in your comment to the other answer you want the div be over a specific part of the background. You can achieve this with background-position.

Problems aligning an element at the bottom of a parent element

I'm trying to align a <div> with a <h2> inside it at the bottom of a parent div. The best way to show you is through code so here's the JSFiddle example: http://jsfiddle.net/3GGa7/
As you can see, the project-title div (and the <h2> inside it) is aligned to the top of the project-header div. I would like it to sink to the bottom of that div, to look like this:
However if I apply a margin-top to project-title it pushes everything down rather than just that div, and if I apply a padding the black background will cover the image.
What's the most elegant way to accomplish this?
Since the .project-title must be contained within the .project-header, give the .project-header a position:relative; and the .project-title a position:absolute;
.project-header {
height: 100px;
position:relative;;
}
.project-title {
background: black;
opacity: 0.75;
position:absolute;
bottom:0px;
left:0px;
right:0px;
}
Check it out http://jsfiddle.net/gXyEU/
This way, whether you use a bigger image, or change its position or margin, you'll never have to worry about the title, it will always be positioned where it should be.
If your picture size is steady. You can try the css below:
.project {
width: 335px;
float: left;
border: 1px solid #ccc;
border-radius: 6px;
}
.project-header {
height: 100px;
}
.project-title {
background: black;
opacity: 0.75;
float:left;
width:100%;
margin-top:25%;
}
.project-title h2 {
color: #fff;
margin-bottom:0px;
float:left;
}
just close your project-header div before start of project-title div like as
<div class="project">
<div class="project-header" style="background-image:url('http://placekitten.com/200/300');" ></div>
<div class="project-title">
<h2>Project title</h2>
</div>
<div class="project-description">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ornare felis id enim dignissim dapibus. Maecenas dui mi, ullamcorper eget semper non, varius quis orci. Suspendisse lobortis nibh sed nisi luctus dictum. Sed vel arcu eros. Etiam id varius neque. Cras ac sapien in est fringilla tempor vitae et est.</p>
</div>
</div>
FIDDLE is here
If you don't mind setting the width of .project-header
.project-header {
width: 335px;
height: 100px;
display: table-cell;
vertical-align: bottom;
}
Modified JSFiddle

Adding a dotted line spacer/infill with CSS

I am working on a restaurant website. The design calls for the typical dotted line infill between a menu item and the price. I have been scouring the net and messing with it for an hour or so now and can't seem to find any good ways to do this with only CSS. I found a couple of other solutions on here that work great if you have a solid color background, however on this site it uses a background image and those solutions wouldn't work.
Example: Menu style "...." - fill in with periods has a good solution, but it sets the background colors to white of the menu item and price to hide the dotted lines behind them, but the page I am building has a background image so any solid color backgrounds would look bad.
I have tried using all kinds of combinations of table-row/table-cell or any other type of CSS display attributes and width settings on the elements, but no dice.
Here is some fake sample markup:
<ul>
<li><span>Soup</span><span class="dots"> </span><span>$2.99</span></li>
<li><span>Ice cream</span><span class="dots"> </span><span>$5.99</span></li>
<li><span>Steak</span><span class="dots"> </span><span>$20.99</span></li>
</ul>
I have been trying to get this to work by using the "dots" class element with a bottom border to fill in the gap, but nothing I try works. I also just put a bottom border on the LI element all the way across the bottom of each row, but that is not what the designer wants. I can only think of doing it in javascript as a last resort, but wanted to see if you guys had any ideas. Or, I can just use tables, but really wanted to avoid that as well.
Thanks!
I would go with something like this:
Example Fiddle
It uses the dotted border on the .dots element and shifts it some pixels to the top.
ul li {
display:table-row;
width:15em;
}
ul li span{
display:table-cell;
}
.dots{
min-width:10em;
position:relative;
bottom:4px;
border-bottom:1px dotted #777;
}
Nice sideeffect - you dont need to float the elements. However this solution uses display:table-cell so this won't work in old IEs (<IE8).
Depending on the background, you could use the li-border solution and replace the solid colors on the span-elements with the background-image itself.
I can be achieved by using definition lists (fiddle):
HTML:
<div id="wrap">
<div class="inner">
<dl>
<dt>$2.89</dt>
<dd><em>Lorem ipsum dolor sit amet </em></dd>
</dl>
<dl>
<dt>$21.89</dt>
<dd><em>In porta nisl id nisl varius ullamcorper</em></dd>
</dl>
<dl>
<dt>$5.99</dt>
<dd><em>Suspendisse augue mauris, mattis ac, commodo quis, lobortis vel, mauris. Etiam dolor neque, iaculis sit amet, tincidunt nec, elementum ut, lorem.</em></dd>
</dl>
<dl>
<dt>$8.99</dt>
<dd><em>Donec sed felis sit amet risus</em></dd>
</dl>
<dl>
<dt>$11.50</dt>
<dd><em>Maecenas ante. Suspendisse pharetra, metus in tempus egestas, purus ante pellentesque purus, at gravida metus elit nec nunc. Etiam ante ligula, porttitor et, euismod commodo, pulvinar id, pede. Curabitur et magna. Vestibulum leo nibh, viverra sed, imperdiet non,</em></dd>
</dl>
<dl>
<dt>$5.99</dt>
<dd><em>Etiam ante ligula,</em></dd>
</dl>
<dl>
<dt>$5.99</dt>
<dd><em>Fusce condimentum</em></dd>
</dl>
<dl>
<dt>$7.55</dt>
<dd><em>Morbi nibh velit, sodales eu</em></dd>
</dl>
<dl>
<dt>$6.50</dt>
<dd><em>Etiam ante ligula,</em></dd>
</dl>
<dl>
<dt>$11.50</dt>
<dd><em>Fusce condimentum</em></dd>
</dl>
<dl>
<dt>$2.50</dt>
<dd><em>Morbi nibh velit, sodales eu</em></dd>
</dl>
<dl>
<dt>$21.50</dt>
<dd><em>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta nisl id nisl varius ullamcorper.</em></dd>
</dl>
</div>
</div>
CSS:
* {margin:0;padding:0}
h1,h2{padding:10px 20px 0}
#wrap{
width:500px;
border:1px solid #eff2df;
margin:20px 20px;
background:#809900;
}
* html #wrap {width:502px;w\idth:500px;}
#wrap .inner{
padding:20px 40px;
border:1px solid #4c7300;
position:relative;
left:-2px;
top:-2px;
background:#eff2df;
color:#4c7300;
width:418px;
}
* html #wrap .inner{width:500px;w\idth:418px;}
#wrap dl{
position:relative;
width:100%;
border-bottom:1px solid #eff2df;
}
#wrap dd{
line-height:1.2em;
position:relative;
padding:0 5em 0 0;
text-align:left;
border-bottom:1px dotted #000;
clear:both;
margin:0 0 .4em 0;
min-height:0;
}
* html #wrap dd{
border:none;
background: url(images/dotted-leader.gif) repeat-x left bottom;
height:1%;
}
#wrap dt{
background:#eff2df;
padding:1px 0 1px 5px;
color:#809900;
position:absolute;
bottom:0px;
right:-1px;
z-index:99;
}
#wrap dd em{
margin:0 ;
position:relative;
top:.25em;
padding:0 5px 0 0;
background:#eff2df;
}
Reference Link

When a child element overflows horizontally, why is the right padding of the parent ignored?

Given this simple structure:
<div id="parent">
<div id="child">Lorem ipsum</div>
</div>
with this CSS:
#parent {
width: 200px;
height: 200px;
padding: 20px;
overflow-x: scroll;
}
#child {
width: 500px;
}
Live demo: http://jsfiddle.net/523me/5/
Notice that the parent has a 20px padding and that the child overflows horizontally (because it is wider). If you scroll the parent all the way to the right, you'll see that the child touches the right edge of the parent.
So, the parent should have a right padding, but it is ignored. It seems that when the child has a fixed width, the right padding of the parent does not apply. (Is this specified by a standard? I would love to know. Please let me know if you find anything!)
Is there a way to force the right padding to be applied in this scenario without having to remove any of the elements from the flow (by floating or positioning)?
Screenshot 1 - The right padding is ignored. This is how all current browsers behave.
Screenshot 2 - The right padding applies. This is what I'm trying to accomplish. (Btw, the screenshot is from IE7, which is the only browser which does not ignore the right padding.)
You're suffering from this problem.
I would solve it by giving a margin to the child (and not a padding to the parent):
body {
padding: 2em;
}
#parent {
width: 200px;
height: 200px;
overflow-x: scroll;
background: gray;
}
#child {
width: 500px;
background: yellow;
margin: 20px;
display: inline-block;
}
<div id="parent">
<div id="child">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras et turpis eu lorem consectetur blandit sed vel ligula. In lorem ligula, lacinia sed aliquet sed, congue quis tortor. In sed magna eros, eget blandit arcu. Nulla sit amet volutpat ipsum. Duis
quis nisl massa. Sed ipsum magna, tempus non malesuada in, gravida et sapien. Fusce a odio nulla, quis ultrices mauris. Maecenas in tellus id massa fringilla molestie.</div>
</div>
Dunno but adding:
#child{
display: inline-block;
}
Seems to fix it: http://jsfiddle.net/523me/6/
I've only tested in latest Chrome, may not be cross-browser
You might change the padding to a border.
padding: 20px;
to
border: 20px solid gray;
No, the padding is not ignored, but it's still inside the parent.
See updated jsFiddle, where you can see that the padding hasn't moved from its original position.
Edit: Hm, there are some anomalies. If you give the inner div a right margin, that gets ignored too. Hm. Upvoting your question.
Apply padding-right to overflowing element itself, and move background to its direct child element.
<div id="parent">
<div id="child"><div>Lorem ipsum...</div></div>
</div>
<style>
#parent {padding-right: 0; }
#child {padding-right: 20px; }
#child > DIV {background: yellow; }
</style>
http://jsfiddle.net/523me/9/