Layouting a small table with HTML and CSS - html

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>

Related

Table cell break word won't shrink

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.

Vertically center element after title with dynamically loaded text all within a static container

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%;
}

Centering text in a fluid layout

I have a website with a fluid/dynamic layout in which I need to center specific text elements between images. Everything is all fine and dandy and I have done so by changing the margins of the text elements, however if I were to change the text inside my p tags, the images would no longer be aligned they way they are or the text would no longer appear exactly centered next to the adjacent images.
JSFiddle that resembles my "problem": http://jsfiddle.net/3s4bhwg4/4/
Ideal image if my JSFiddle does not look correct:
Is there a more maintainable way to achieve the same results of centering the text or is using margins to this extent acceptable/considered good practice?
I'm very rusty with web design, so I'll take any criticism happily.
Note: Resizing the JSFiddle width seems to break the layout. However resizing it on my local webpage keeps it constant....
CSS:
#wrapper{
MARGIN-LEFT: auto;
MARGIN-RIGHT: auto;
WIDTH: 100%;
}
.row{
width: 100%;
}
/*Please execuse my use of left/right in naming my ids. */
#contentleft{
float: left;
width: 60%;
}
#contentleft h1{
margin: 30% 5% 0 40%;
}
#contentleft p{
margin: 0 5% 0 40%;
}
#contentright{
float: right;
width: 40%;
}
#contentright p{
margin: 17% 30% 43% 10%;
}
img{
width: 100%;
}
HTML:
<div id="wrapper">
<div class="row">Header</div>
<div id="contentleft">
<IMG src="http://img2.wikia.nocookie.net/__cb20081223173835/uncyclopedia/images/7/7e/Mountain.jpg"></IMG>
<H1>Random.</H1>
<P> Both texts must be centered next to their adjacent images as well. </P>
</div>
<div id="contentright">
<P>The margins of this text pushes the image down so it aligns with the corner of the other image.
</P>
<IMG src="https://c1.staticflickr.com/5/4081/4811391918_7d607682b6_z.jpg"></IMG>
</div>
</div>
This is the closest I could get using a table as suggested by #JStephen: JSFIDDLE
The only way I could make it work was to keep one image un-scaled.
And I couldn't get them to meet exactly in the corners.
EDIT:
Working correctly now...
I managed to hack it by inserting the lower image in the cell above it in the first row, setting its height to 1px and opacity to 0 and floating it. This works because the table layout is fixed so the first row is used to format the table. (By floating the hidden image, the centering of the text is unaffected.) I then set the width of the visible copy of the second image to 100%.
Added padding: 0; in td as well as border-collapse: collapse; in Table to make the corners touch exactly like your pic. (It seems the default padding is not zero)
It works as long as the height of the text is less than that of the (visible) images
HTML
<body>
<div class="row">Header</div>
<table id="wrapper">
<tr id="cont-top">
<td>
<img src="http://img2.wikia.nocookie.net/__cb20081223173835/uncyclopedia/images/7/7e/Mountain.jpg" />
</td>
<td>
<img src="https://c1.staticflickr.com/5/4081/4811391918_7d607682b6_z.jpg" />
<p>The margins of this text pushes the image down so it aligns with the corner of the other image.</p>
</td>
</tr>
<tr id="cont-bottom">
<td>
<h1>Random.</h1>
<p> Both texts must be centered next to their adjacent images as well. </p>
</td>
<td>
<img src="https://c1.staticflickr.com/5/4081/4811391918_7d607682b6_z.jpg" />
</td>
</tr>
</table>
</body>
CSS
#wrapper {
MARGIN-LEFT: auto;
MARGIN-RIGHT: auto;
height: 100%;
width: 100%;
table-layout: fixed;
border-collapse: collapse;
z-index: 0;
}
td, tr{
padding: 0;
position: relative;
}
td{
/*outline: 1px dotted red;*/
}
.row {
width: 100%;
padding: 0.5em;
height: 4%;
}
/*top row********/
#cont-top {
height: auto;
margin: 0;
padding: 0;
}
/*image*/
#cont-top td:first-child {
width: 60%;
}
#cont-top img{
width: 100%;
vertical-align: bottom;
z-index: 20;
}
/*text*/
#cont-top td:last-child{
padding: 0;
}
#cont-top td:last-child p {
margin: 0 10px;
vertical-align: central;
}
/*formatting hack*/
#cont-top td:last-child img{
width: 100%;
height: 1px;
line-height: 1px;
float: left;
/*opacity: 0;*/
}
/*bottom row********/
#cont-bottom {
height: auto;
position: relative;
}
/*image*/
#cont-bottom td:last-child {
vertical-align: top;
}
#cont-bottom img{
vertical-align: top;
width: 100%;
left: 0;
z-index: 20;
}
/*text*/
#cont-bottom td:first-child {
vertical-align: central;
padding: 0 10px;
}

Fixed height of table row in html

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.

Sum of percent widths not rounded to 100%

I want to make a multi-segment progress bar.
It has to be horizontally centered, with a maximum width, but not a static one, so it can shrink if there is not enough space.
The problem is that sometimes the total progress is at 100%, but the segments could be at 33.33% and 66.66%.
The percentages are being calculated based on the width of the document, which may be an odd number, so the bar segments' widths are rounded in a way that leaves one pixel empty on the bar.
HTML
<div class="CENTER">
<div class="BAR">
<div class="SEGMENT ONE" style="width: 33.33%;"></div>
<div class="SEGMENT TWO" style="width: 66.66%;"></div>
</div>
</div>
CSS
.CENTER {
max-width: 400px;
margin-left: auto;
margin-right: auto;
}
.BAR {
height: 10px;
}
.SEGMENT {
float: left;
height: 100%;
}
.BAR { background-color: #F00; border: 1px solid #000; }
.SEGMENT.ONE { background-color: #FDA; }
.SEGMENT.TWO { background-color: #ADF; }
Play around with the width of the window after it's big enough for the bar to reach its maximum width.
There will be a red one pixel wide section on the right side of the bar.
How can I avoid it?
Example: http://jsfiddle.net/CV6fp
Can you do it using that same HTML and without JavaScript, CSS?
Maybe with table display?
http://jsfiddle.net/CV6fp/6/
.CENTER {
max-width: 400px;
margin-left: auto;
margin-right: auto;
}
.BAR {
height: 10px;
display: table;
width: 100%;
}
.SEGMENT {
display: table-cell;
height: 100%;
}
.BAR { background-color: #F00; border: 1px solid #000; }
.SEGMENT.ONE { background-color: #FDA; }
.SEGMENT.TWO { background-color: #ADF; }
Here is how I would do it:
http://jsfiddle.net/CV6fp/3/
Basically, drop the width property off the div with class TWO. Then make the same div NOT float left:
<div class="CENTER">
<div class="BAR">
<div class="SEGMENT ONE" style="width: 33.33%;"></div>
<div class="SEGMENT TWO"> </div>
</div>
</div>
And the style change:
.SEGMENT.TWO { background-color: #ADF; float:none; }
This means that second segment no longer floats:left, but I do think this may be what you are looking for.
Update: And finally after much soul searching, a CSS only solution to solve all the issues mentioned on this page:
http://jsfiddle.net/CV6fp/7/
Two changes to CSS: (1) segments set to float:right, and (2) .SEGEMENT.ONE to override that and always float:left
.SEGMENT {
float: right;
height: 100%;
}
.SEGMENT.ONE { background-color: #FDA; float:left; }
In this case you may need to reduce accuracy to the tenth's place and use a ceiling rounding function on the final segment. This way you would get 33.3% and 66.7%.
Try: .SEGMENT:last-child { float: none; width: auto !important; }. This should make the last segment to fill the remaining space.