I’ve tried to create a layout with a topbar and under it a split layout. The problem I had is that the width and height should automatically fit to the browser size.
So I tried it with a table:
body {
margin: 0;
padding: 0;
min-height: 500px;
min-width: 600px;
}
table {
border-collapse: collapse;
}
.topbar {
height: 50px;
position: relative;
background: grey;
}
.layout_table {
height: 100%;
width: 100%;
}
<body>
<table class="layout_table">
<tr>
<td class="topbar">
hallo
</td>
</tr>
<tr>
<table width="100%">
<td width="20%" style="background: blue;">
</td>
<td width="80%" style="background: yellow;">
</td>
</table>
</tr>
</table>
</body>
JSFiddle
Now the result is mostly correct. The problem is that the second row of the first table doesn’t have a full height.
How can I fix this?
Instead of using <table> elements for layout, which is not recommended as the element should only be used for tabulated content, you should try using modern alternatives. What you are trying to do can be achieved with a combination of calc() and float or flex specifications. The float property is better supported by older browsers, but flex (from the CSS3 Flexbox specification) offers more layout possibilities.
In my example below I have used the flexbox specification for both (1) vertically aligning your topcontent text and (2) for distributing space between the blue and yellow columns under it. The latter of which can be easily achieved by float, but the reason of avoiding it is because of the need to clear floats properly.
body {
margin: 0;
padding: 0;
min-height: 500px;
min-width: 600px;
}
.topbar {
display: flex;
align-items: center;
height: 50px;
background-color: grey;
}
.content {
display: flex;
height: calc(100vh - 50px);
min-height: 450px; /* minimum parent height minus topbar height */
}
.content .c1 {
width: 20%;
height: 100%;
background-color: blue;
}
.content .c2 {
width: 80%;
height: 100%;
background-color: yellow;
}
<div class="topbar">
<span>Hello</span>
</div>
<div class="content">
<div class="c1"></div>
<div class="c2"></div>
</div>
Related
I often use this HTML/CSS structure to create a mobile-friendly table (It changes layout on narrow (mobile) screens; something very lacking in CSS frameworks) and it has been quite reliable for me. In my main project I have several tables with lots of data and varying widths.
If you open this codepen and change the view to 'debug' you can shrink the page width. Past 500px the table layout will change. The thead is hidden, secondary labels are shown and the tds are set to display: flex. (I like to use the responsive device toolbar in the inspector).
Under the table is a more simple set of divs, that behaves the way I want the divs inside the TD to work, but for some reason, the second div inside the td stops shrinking at a certain point. I have tried different combinations of word-wrap and white space but so far no luck. Seems the difference has to do with these divs being inside a table...
Is this just a limitation of tables or is there a way I can make the right div shrink like the second example?
Thanks!
https://codepen.io/sinrise/pen/qoypYJ
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>number</th>
<th>content</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="td-label">number</div>
<div>this is the first one</div>
</td>
<td>
<div class="td-label">number</div>
<div>this is the second one</div>
</td>
</tr>
</tbody>
</table>
<div class="cont">
<div class="in1">oneoneone oneone one oneoneoneoneoneon</div>
<div class="in2">two two twotwotwo twotwotwotwo</div>
</div>
table { width: 100%; table-layout: fixed; margin: 0 0 10px; }
th { padding: 10px 10px 0; text-align: left; }
td { padding: 10px; border: 1px solid #ccc; }
.td-label {
display: none;
min-width: 100px;
max-width: 100px;
font-weight: bold;
}
#media(max-width: 500px) {
thead { display: none; }
td {
display: flex;
margin: 0 0 10px;
> div:not(.td-label) {
word-wrap: break-word;
min-width: 1px;
}
}
.td-label {
display: table;
}
}
.cont {
display: flex;
border: 1px solid black;
> div {
&:first-of-type {
min-width: 100px;
max-width: 50px;
}
min-width: 1px;
border: 1px solid #aaa;
word-wrap: break-word;
}
}
The trick is to set the table width to 100%, add a min-width to the second div, and set display: table on the second div. I updated the pen and code above to reflect.
I'm very novice to HTML and CSS and have not yet "gotten it" how it all works.
I am trying to achieve a table made of two rows, in which the first row only has one column and spans over the two columns of the second row.
In the first row I have an input box and I'd like the row to conform to the height of this input box. On the bottom left I have a button with its own style and I'd like the row (and cell) to conform to the size of the button. On the bottom right I have an image and I'd like the image to scale (preserving its aspect ratio) such that it either fills the height of the row (and floats to the right) or the width of the cell and centers vertically.
The table will fill its container (a div) horizontally.
Can anyone give me hints?
I don't necessarily need a table element, just something that achieves the effect without me having to specify pixel sizes to keep everything scalable.
Here is what I have now (some garbage may still be in there...):
table {
display: table;
table-layout: auto;
width: 100%;
}
tr {
display: table-row;
width: auto;
clear: both;
}
input {
font-size: 16px;
}
input[name="text"] {
line-height:1.875;
display:table-cell;
width:100%;
}
input[type="submit"] {
border: 0;
border-radius: 0;
background: #d7b221;
box-shadow: none;
color: white;
font-size: 16px;
font-weight: bold;
line-height: 1;
padding: 1.4em 1.6em 1.2em;
}
img {
width: auto;
height: 52px;
}
a {
display: block;
float: right;
}
<form>
<table>
<tr>
<td colspan="2">
<input name="text" placeholder="Enter some text here"/>
</td>
</tr>
<tr>
<td><input type="submit" value="Click Here"/></td>
<td><img src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/car.svg"/></td>
</tr>
</table>
</form>
I guess it ultimately boils down to this:
#container {
border:1px solid red;
}
#main_img {
height: 30px;
width: 30px;
}
#dep_img {
max-width: 100%;
max-height: 100%;
}
<div id="container">
<img id="main_img" src="http://i.stack.imgur.com/xkF9Q.jpg">
<img id="dep_img" src="http://i.stack.imgur.com/xkF9Q.jpg">
</div>
Is there any way in which the size (height) of the main image can dictate the size (height) of the dep image?
Why are you using a table to layout in the first place when you can do all that with just CSS.
Learn CSS from this site: http://learnlayout.com/
If all you want is that all images are of the same size then that can be easily addressed by using a class for the images.
#container {
border:1px solid red;
padding: 5px;
}
.my-kind-of-image {
height: 30px;
width: 30px;
}
<div id="container">
<img class="my-kind-of-image" src="http://i.stack.imgur.com/xkF9Q.jpg">
<img class="my-kind-of-image" src="http://i.stack.imgur.com/xkF9Q.jpg">
<img class="my-kind-of-image" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/car.svg"/>
</div>
This is driving me crazy and I don't think it is even possible at this point, but I would like to consult the Internet Gods before I give up.
Visual representation of what I want:
I want the text to align at the top-left of the container, and the image to align itself in the center of the space that is leftover after (if) the text wraps.
Please see demo
I'm using flexbox and margin: 0 auto to get the centering I want, and position: absolute on the h2 element works fine if the image is long, but looks terrible with tall image.
Is there some flexbox magic I can use to take into account the height of the dynamically loaded h2 element and make the image centered within the rest of the free space?
Constraints:
The parent container must be 200px by 200px.
Image can not be distorted (stretched).
I was able to find my own solution by combining #Claudio's table idea and some position absolute magic.
Here is the solution demo with both tall and wide images:
DEMO
HTML:
<div class="main-box">
<table>
<tr>
<td class="box-title">
<h2>
My title here. :) add some more text
</h2>
</td>
</tr>
<tr>
<td class="box-img">
<img src="//i.imgur.com/NOzWHFF.png" alt="Google">
</td>
</tr>
</table>
</div>
<div class="main-box">
<table>
<tr>
<td class="box-title">
<h2>
My title here. :) add some more text
</h2>
</td>
</tr>
<tr>
<td class="box-img">
<img src="https://upload.wikimedia.org/wikipedia/commons/e/e0/Long_March_2D_launching_VRSS-1.jpg" alt="Google">
</td>
</tr>
</table>
</div>
CSS:
*{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.main-box{
width: 200px;
height: 200px;
border: 2px solid #000;
background-color: #FFF;
position: relative;
}
.main-box table{
width: 100%;
height: 100%;
border-spacing:0;
}
.main-box .box-title{
background-color: rgba(0, 0, 0, 0.1);
height: 1px;
}
.main-box .box-title h2{
margin: 0;
padding: 5px;
font-family: Helvetica, Arial, sans-serif;
}
.main-box .box-img{
text-align: center;
vertical-align: middle;
padding: 5px;
position: relative;
}
.main-box .box-img img{
max-width: 100%;
max-height: 100%;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
It is not impossible, nothing is inpossible. :)
So, I was trying hard do something that work, and after spend much time thinking and testing... The solution!! Unfortunately, is using table (I'm sorry, but its the only way to do it only with HTML and CSS).
The base of the structure is simple. We have a main div with the dimentions that we want (200px X 200px). Inside it, we have a table with two lines (One to our title, and the other to our beautiful img)
After we style the structure, removing border-spacing... removing margin of h2 and things like that. We need (here is the trick) apply height: 1px; to our first line of the table (The line of the title).
Why height: 1px;?
Well, the table element applies its size following the content. We applying height: 1px;, the line will not get literally with 1px of height, it means that the line will take the less height as possible respecting the content. Doing so, the other line (the line of the image) will get all the leftover space to it, and after it's only apply vertical-align: middle; and text-align: center; in order to centering the image.
After all the explanation... the code:
https://jsfiddle.net/u61y62r8/
I hope it can help you. :)
That should do the trick.
<div class="container">
<div class="inner">
<h2>This is a title</h2>
</div>
<div class="inner-2">
<img src="https://thesingleplayermode.files.wordpress.com/2013/05/pokemon-banner.jpg">
</div>
</div>
CSS:
.inner {
width: 100%;
height: 50px;
}
.inner-2 {
height: calc(100% - 50px);
display: flex;
justify-content: center;
align-items: center;
}
.img {
max-width: 100%;
max-height: 100%;
}
I have two tables inside divs inside another div:
HTML
<div class="container center">
<div class="thing">
<table class="tabel center" style="width:230px">
<tr><td>Example</td></tr>
</table>
</div>
<div class="thing">
<table class="tabel center" style="width:230px">
<tr><td>Example</td></tr>
</table>
</div>
</div>
CSS
.container {
width: 100%;
overflow: hidden;
float: left;
border: 1px solid red;
text-align: center;
}
.tabel {
border: 1px solid black;
border-collapse: collapse;
padding: 5px;
}
.thing {
width: 50%;
float: left;
min-width: 230px;
}
.center {
margin: 0 auto;
}
The two cells are centered correctly
[Image deleted by host]
but when the width of the screen gets too small, the cells go underneith each other (what I want), but they no longer get centered:
[Image deleted by host]
So what I want them to look like:
[Image deleted by host]
You have to remove float: left;, set display: inline-block; and eliminate white space between them.
.thing {
width: 50%;
display: inline-block;
/* float: left; */
min-width: 230px;
vertical-align: top;
}
fiddle: http://jsfiddle.net/3g7xk0sj/1/
Just use media query http://jsfiddle.net/3g7xk0sj/3/
#media all and (max-width: 480px) {
.thing {
width: 100%;
}
}
The problem you are facing is that you are telling each floating DIV (class thing) to be 50% width a minimum of 230px, but it will never span to 100% of the container's width (unless the container is also 230px wide). So the auto margin will only be applied within class .thing's width, which is 230px. Now add to that your table that is ALSO 230px wide, no margin will ever be rendered and consequently you tables will never float in the center.
Try using a CSS media query instead to force a 100% width on class thing when the screen size goes below 460px (230px*2).
Alternatively, use display: inline-block instead of floating, as emmanuel suggested.
Remove float:left & use margin:0 auto in thing class
Demo http://jsfiddle.net/3g7xk0sj/4/
.container {
width: 100%;
overflow: hidden;
float: left;
border: 1px solid red;
text-align: center;
}
.tabel {
border: 1px solid black;
border-collapse: collapse;
padding: 5px;
}
.thing {
margin: 0 auto;
width: 50%;
}
<div class="container center">
<div class="thing">
<table class="tabel center" style="width:100%">
<tr><td>Example</td></tr>
</table>
</div>
<div class="thing">
<table class="tabel center" style="width:100%">
<tr><td>Example</td></tr>
</table>
</div>
</div>
I have a table hosted in a div. Neither the table nor the hosting div has a height specified.
After the table header row, each subsequent row looks like this:
<tr class="movie-info-row">
<td>
<div class="movie-cover">
<img class="movie-image" src="" />
<a class="movie-link" href="" target="_blank">IMDb</a>
</div>
</td>
<td colspan=5>
<div class="movie-details">
<p class="movie-file"></p>
<div class="movie-div-left">
<p class="movie-category"></p>
<p class="movie-director"></p>
<p class="movie-insertdate"></p>
</div>
<div class="movie-description-container">
<p class="movie-description"></p>
</div>
</div>
</td>
</tr>
I want each table row (except for the header) to have the same fixed height but I just can't get it to work after hours of trying all kinds of approaches (and of course searching on stackoverflow and elsewhere).
My css (in less syntax) looks like this:
.movie-info-row {
height: 240px;
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
height: 100%;
overflow: hidden;
}
}
.movie-cover {
border: 1px solid black;
width: 130px;
height: 100%;
overflow: hidden;
}
.movie-details {
border: 1px solid black;
height: 100%;
overflow: hidden;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
float: left;
width: 40%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
float: right;
width: 60%;
overflow: hidden;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
As you can see I have fixed the height of the row to 240px and for good measure have each td height set to 100% with overflow hidden.
The trouble maker is the description text, which can be quite long and it messes with the table row height. As you can see I have set overflow to hidden in many places (which is probably overkill).
Note: This is not browser specific. I am not even using IE. I am testing it with firefox and chrome (both latest versions).
I am really at a loss. What am I doing wrong? Any help would be greatly appreciated.
ETA:
Here's a picture of a table row as it looks now: SampleRow
As you can see the description text takes the row height with it. I want it limited to a fixed height - basically the hight of the title image. And yes, I want all the information (with more to come) in there. So that is non-negotiable.
Too many hiddens and floats and whatnot. Simplify and conquer. Also you have nested selectors inside of another selector (p{} and td{})
Demo Fiddle
CSS:
.movie-info-row {
height: 240px;
}
p {
margin-top: 2px;
margin-bottom: 2px;
}
td {
border: 1px solid black;
height: 100%;
}
div, p {
display: table-cell;
}
.movie-cover {
width: 130px;
overflow: hidden;
}
.movie-details {
height: 100%;
width: 100%;
}
.movie-file {
font-size:larger;
}
.movie-div-left {
width: 35%;
vertical-align: top;
display: inline-block;
}
.movie-description-container {
display: inline-block;
width: 55%;
vertical-align: top;
}
.movie-description {
overflow: hidden;
}
By the looks of your HTML all of your data will go into one table cell is this how you want it?
Why not structure it like using individual tags for the headers with a colspan of what ever and then do a new for each row you need along with its data like this?
<tr>
<th colspan=2>Header</th>
</tr>
<tr>
<td>cell 1 data</td>
<td>cell 2 data</td>
<tr>
Then you can do this in the css, which would give you this same fixed height for all the rows:
tr {
height: 240px;
}
That way you can just use the table headers to describe each column and use a lot less code to make it work properly. Or from what I understand you are trying to do.