Forms in tables reproduced with css "display: table" property - html

I'm trying to reproduce a table with the CSS display: table/table-row/table-cell properties. However, it seems that <form> elements contained in tables created this way mess up with the tables' structure. Alignment would be off, a full row containing a form would be limited to the width of the previous' row first cell, etc. It goes all over the place.
Is it possible to make forms behave like other elements in this situation? I defined forms as display: inline in the CSS but that doesn't help.
My code (Simplified it for readability)
form {
display: inline;
}
.calendarTable {
display: table;
margin: auto;
width: 60%;
}
.calendarRow {
display: table-row;
}
.calendarCell {
display: table-cell;
text-align: left;
padding: 10px;
vertical-align: middle;
}
<div class="main">
<div class="calendarTable">
<div class="calendarRow">
<p class="calendarCell">Some title</p>
<p class="calendarCell">Some title</p>
<p class="calendarCell">Some title</p>
</div>
<?php some php loop ?>
<form method="post">
<div class="calendarRow">
<p class="calendarCell">
<some inputs>
</p>
<p class="calendarCell">
<some inputs with formaction>
</p>
</div>
<br>
</form>
<?php end php loop; ?>
<form method="post">
<div class="calendarRow">
<p class="calendarCell">
<some inputs>
</p>
<p class="calendarCell">
<some inputs with formaction>
</p>
</div>
</form>
</div>
</div>

UPDATE
As per OP's request,
I wanted to know if it is possible to have forms behaving properly in this scenario.
Indeed it is possible, I'm not sure if it's valid, but it works flawlessly.
SOLUTION
Assign each <form> display:table-row
See updated Snippet.
There were <form>s wrapped around the .calendarRows
The 2nd and 3rd rows had only 2 cells each, while the 1st row had 3 cells.
If we were to apply invalid HTML to <table>, <tr>, and <td>, then they would also perform erratically as well. In this Snippet I have:
Removed the <forms>
Added 1 cell to the 2nd and 3rd rows
Added table-layout:fixed to control the table's behavior even more. Note that I have declared each cell to be 32% wide. Normally, this would be hard to accomplish because of the 3rd column having more content than the other columns.
Added outlines to demonstrate how cells are correctly aligned.
SNIPPET
.calendarTable {
display: table;
margin: auto;
width: 60%;
table-layout: fixed;
}
.calendarRow {
display: table-row;
}
.calendarCell {
display: table-cell;
text-align: left;
padding: 10px;
vertical-align: middle;
width: 32%;
}
p {
outline: 1px solid black;
}
.red {
color: red;
font-weight: 700
}
<div class="main">
<div class="calendarTable">
<form class="calendarRow">
<p class="calendarCell">Some title</p>
<p class="calendarCell">Some title</p>
<p class="calendarCell">Some title</p>
</form>
<form class="calendarRow">
<p class="calendarCell">Some new title</p>
<p class="calendarCell">Some new title</p>
<p class="calendarCell red">This cell was missing</p>
</form>
<form class="calendarRow">
<p class="calendarCell">Some new title</p>
<p class="calendarCell">Some new title</p>
<p class="calendarCell red">This cell was missing</p>
</form>
</div>
</div>

Related

Equal distribution of height across multiple Flex Columns [duplicate]

This question already has answers here:
Align child elements of different blocks
(3 answers)
Closed 10 months ago.
We have the following problem:
It is about accommodating three boxes in a row, which should have the same height. In addition, the boxes each contain two parts: an introductory block and a detailed description.
If we now build the whole thing with Bootstrap 4, this is the structure:
/**
* CSS just for visualization
**/
.block-wrap {
background: lightgrey;
height: 50px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
</div>
We want the blocks (cols) to always have the same height - this means that the tallest block (based on the content) dictates the height of the others. We achieve this by setting the height of all blocks to 100 percent. It will look somewhat like this:
Now it gets tricky. While the blocks should always have the same height among themselves, the detail blocks should always start at the same height, like this:
Any idea how we can achieve this - it is important that the responsive behavior is retained and the blocks also make sense on mobile.
Edit:
I found a simple solution while stumbling across another problem - in hindsight I wonder why I didn't think of that right away, after all I've already worked with it. Thats how it works:
Bootstrap comes with a function to sort the columns. So in the end I just created a row with 6 columns. I then gave them a sorting on the different devices during the break.
I have recreated it again for you to illustrate:
Codepen fullscreen
we can use table to do that. not sure if we can do that flex box or grid without using javascript
.container {
border: 1px solid black;
border-collapse: collapse;
}
.intro {
background:lightblue;
}
.intro div{
background:orange;
}
.details div{
background:lightgreen;
}
.details {
height:100px;
background:lightblue;
}
table td {
width: 1%;
border: 1px solid black;
padding:10px;
vertical-align:top;
}
table td.details{
vertical-align:bottom;
}
.ch-50 {
height: 5em;
}
.ch-75 {
height: 7.5rem;
}
.ch-100 {
height: 10rem;
}
.ch-20 {
height: 2rem;
}
table{width:100%;}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<table class="container">
<tr>
<td class="intro ch-50">
<div class="h-75"></div>
</td>
<td class="intro ch-75">
<div class="h-100"></div>
</td>
<td class="intro ch-100">
<div class="h-50"></div>
</td>
</tr>
<td class="details">
<div class="h-50"></div>
</td>
<td class="details">
<div class="h-75"></div>
</td>
<td class="details">
<div class="h-100"></div>
</td>
<tr>
</tr>
</table>
/**
* CSS just for visualization
**/
.row {
display: flex;
}
.block-wrap {
background: lightgrey;
flex: 1;
border: 1px solid;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-4 block-wrap">
<div>
Intro text
Intro text
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
</div>
<div>
Detais text
</div>
</div>
<div class="col-4 block-wrap">
<div>
Intro text
Intro text
Intro text
Intro text
</div>
<div>
<p>Detais text</p>
<p>Detais text</p>
<p>Detais text</p>
<p>Detais text</p>
</div>
</div>
</div>
Please check the properties of flex that I have given to block-wrap. You have to give class to Intro Text as well if you want the height of that column to be same as well

Want to align two words in the same line in css

I have two words that will change after some JavaScript coding. They will be arrays. I can perform the JavaScript coding well, but I want them to be aligned instead of one above the other:
<div class="testArrayDiv">
<input type="text" id="testArrayText" value="aqui" class="testArrayText">
<p id="pTextIng" class="pTextIng">Inglés</p>
<p id="pTextPor" class="pTextPor">Português</p>
<button id="btnArray" class="btnArray">Test Array</button>
</div>
My CSS coding:
.pTextIng {
margin-left: 45%;
}
.pTextPor {
margin-left: 45%;
}
The words "Inglés" and "Português" will become columns after some Javascript commands, but they are not aligned and I want them to be aligned.
.pTextIng {
border:1px solid black;
width:80px;
display:inline-block;
}
.pTextPor {
border:1px solid red;
width:80px;
display:inline-block;
}
<div class="testArrayDiv">
<input type="text" id="testArrayText" value="aqui" class="testArrayText">
<p id="pTextIng" class="pTextIng">Inglés</p>
<p id="pTextPor" class="pTextPor">Português</p>
<button id="btnArray" class="btnArray">Test Array</button>
</div>
<p> automatically inserts a line break after the text. If you do not want this you should use <span>. I assume you want both words on the same line as your input field, so you should put both <span> elements inside a <div> and apply margin-left to that.
HTML:
<div class="indentation">
<span id="pTextIng" class="pTextIng">Inglés</span>
<span id="pTextPor" class="pTextPor">Português</span>
</div>
CSS:
.indentation {
display: inline-block;
margin-left: 45%;
}
If you make a div with both p inside like:
<div class="testArrayDiv">
<input type="text" id="testArrayText" value="aqui" class="testArrayText">
<div class="idiomas">
<p id="pTextIng" class="pTextIng">Inglés</p>
<p id="pTextPor" class="pTextPor">Português</p>
</div>
<button id="btnArray" class="btnArray">Test Array</button>
</div>
And then you make this div element flex and flex-direction: row
.idiomas{
display: flex;
flex-direction: row;
}
You need to add vertical-align: top; to fix the issue
.testAlign p {
display: inline-block;
vertical-align: top;
/* other styles */
}
and also that <p> tags need to be inside a <div>
<div class = "testAlign">
<p id="pTextIng" class="pTextIng">Inglés</p>
<p id="pTextPor" class="pTextPor">Português</p>
</div>

How to vertical align text to the center in the bottom left footer

It is a single row made of 3 columns.
I want to make the "h5 class:footer-small" vertical aligned to the div "class: col-1"
I found out that using display: inline-block, it made the text vertical aligned in the center. But I did not understand how was it possible? Can someone explain why using display:inline-block worked?
HTML
<footer>
<div class="row-4">
<div class="col-1">
<p class="col-1">
<h5 class="footer-small">Seattle<br>Grace<br>Hospital</h5>
</p>
</div>
<div class="col-5">
<h5 class="footer-desc">He is a Bowdoin College graduate and attended Columbia University College <br>of Physicians and Surgeons</h5>
</div>
<div class="col-6">
<h2 class="footer-frase">McDreamy</h2>
<em class="footer-frase">"It's a beautiful night to save lives"</em>
</div>
</div>
</footer>
you can simply do it using css3 flexbox concept
add the following styles to your col-1
display:flex;
align-items:center;
justify-content:center;
Note: you can't declare a header tag (<h1>,<h2>,etc..) inside a paragraph tag(<p>) ,so replace it by <span> tag or any other tags
div.row-4{
display:flex;
color:#fff;
}
div.row-4 div{
padding:5px;
}
.col-6{
background:#73819b;
flex:2;
}
.col-5{
background:#438cab;
flex:2;
}
.col-1{
background:#438cab;
display:flex;
align-items:center;
justify-content:center;
}
<footer>
<div class="row-4">
<div class="col-1">
<span class="col-1">
<h5 class="footer-small">Seattle<br>Grace<br>Hospital</h5>
</span>
</div>
<div class="col-5">
<h5 class="footer-desc">He is a Bowdoin College graduate and attended Columbia University College <br>of Physicians and Surgeons</h5>
</div>
<div class="col-6">
<h2 class="footer-frase">McDreamy</h2>
<em class="footer-frase">"It's a beautiful night to save lives"</em>
</div>
</div>
</footer>
You have two to do this:
1- Set line-height.
2- Or set the height itself.
.row-4 {
background-color: lightblue;
height: 200px;
line-height: 200px; /* <-- this is what you must define */
vertical-align: middle;
vertical-align: middle;
}
h2, em
{
display: inline-block;
vertical-align: middle;
line-height: 14px; /* <-- adjust this */
}
em {
font-size: 12px;
font-weight: normal;
display: block;
margin-top: 10px;
}
<footer>
<div class="row-4">
<h2 class="footer-frase">
McDreamy
<em class="footer-frase">"It's a beautiful night to save lives"</em>
</h2>
</div>
</footer>
BTW: I did some modifications.
There is also another way, which is using flex containers.

display into fixed html area

In my html I get 'response' from controller. Number of lines in the response varies (max is 3).
What is the best way to 'reserve' 3 lines on my html page so the next div with 'SOMETHING' paragraph is not scrolled down by 'response' ?
<div class="row">
<p ng-bind-html="response"></p>
</div>
<div class="row">
<p>SOMETHING</p>
</div>
Using CSS, fix the height occupied by your 3 rows and use overflow to scroll within that fixed height div.
CSS Overflow might help you.
.row-fixed-height {
height: 150px;
overflow: scroll;
}
and in HTML:
<div class="row-fixed-height">
<p ng-bind-html="response"></p></div>
Since the height of the lines varies based on font and font size, I would use line breaks to "reserve" the three lines. If you were to use for instance a fixed height on the div or p, it might jump around on a different browser that uses a different font.
Live Demo:
#response {
background: red;
}
<div class="row">
<p id="response" ng-bind-html="response">
<br />
<br />
<br />
</p>
</div>
<div class="row">
<p>SOMETHING</p>
</div>
JSFiddle Version: https://jsfiddle.net/rspyho74/
As oori pointed you, this is is about CSS, not Angular. The easiest way to fix the height to 3 lines is using the em unit:
.row{
margin: 10px;
padding: 5px;
border: 1px solid #000;
border-radius: 5px;
}
p{
float: left;
margin: 0 5px;
padding: 5px;
border: 1px solid #000;
height: 3em;
}
<div class="row">
<p ng-bind-html="response"></p>
<p ng-bind-html="response">Line 1</p>
<p ng-bind-html="response">Line 1<br>Line 2</p>
<p ng-bind-html="response">Line 1<br>Line 2<br>Line 3</p>
<div style='clear: both;'></div>
</div>
<div class="row">
<p>SOMETHING</p>
<div style='clear: both;'></div>
</div>
As you can see, the paragraph keeps its height no matter how many lines there are. If you remove the height property you can see the difference.

Re-using floatLeft and floatRight to right align text

How can i right-align text as below. I want product, price and year to be right-aligned.
product Computer
price $1500
year 2013
Currently the html code below gives layout as shown
product Computer
price $1500
year 2013
<div style="clear: both;display: block;">
<p style="float: left">
<strong>product</strong>
</p>
<p style="float: left">
<span>Computer</span>
</p>
</div>
<div style="clear: both;display: block;">
<p style="float: left">
<strong>price</strong>
</p>
<p style="float: left">
<span>$1500</span>
</p>
</div>
<div style="clear: both;display: block;">
<p style="float: left">
<strong>year</strong>
</p>
<p style="float: left">
<span>2013</span>
</p>
</div>
try display: inline-block, does wonders
Try aligning the left-floated words with text-align:right;.
Give the <p> tags some width and margin to your last child element inside the <div>. Then assign text-align: right to your first child element. It should look something like this jsFiddle example.
I would solve it using inline-block elements instead of floating ones. To stick a little to your markup you could do:
HTML
<div class="row">
<span>product</span>
<span>computer</span>
</div>
<div class="row">
<span>price</span>
<span>$1500</span>
</div>
CSS
div.row > span {
display: inline-block;
width: 100px;
text-align: right;
margin: 0 20px 0 0;
}
div.row > span:last-child {
width: 200px;
text-align: left;
}
Demo
Try before buy
As a note: You might think of using another element for your content:
A paragraph is typically a run of phrasing content that forms a block of text with one or more sentences that discuss a particular topic, as in typography, but can also be used for more general thematic grouping. For instance, an address is also a paragraph, as is a part of a form, a byline, or a stanza in a poem.
If your data is actually tabular, you can use a <table>-element instead. You can also go with some markup like I did, or you can even use a definition list <dl> or an unsorted list <ul>.
Edit
As requested in the comments. Here's a version using a table:
HTML
<table>
<tbody>
<tr>
<td>Product</td>
<td>Computer</td>
</tr>
<tr>
<td>Price</td>
<td>1500 USD</td>
</tr>
</tbody>
</table>
CSS
table {
width: 350px;
}
table > tbody > tr > td:first-child {
width: 100px;
padding: 0 50px 0 0;
text-align: right;
}
Demo
Try before buy