A CSS grid mystery: padding in grid items - css

Okay then, so I made a nice-looking email-me form using CSS grids. Everything's fine and dandy except when I try to apply some padding on the form elements. Things then start to flow out of the grid.
It seems like the grid system doesn't take padding inside the elements into account when it calculates the final size of the grid items. I tried using fr-s and auto for the width of these elements, and all sorts of useless hacks, but nothing really works.
Here's the code and some screenshots to help you all feel my pain. :D
Without padding in the input fields:
https://imgur.com/a/NB1RcVS and
https://imgur.com/a/nz5lvIw
With padding:
https://imgur.com/a/Ak6CvlX and
https://imgur.com/a/hqLlxBr
<form id="email">
<div class="form-group" id="form-name">
<label for="name-field">Name</label>
<input type="text" name="name-field" id="name-field" required>
</div>
<div class="form-group" id="form-address">
<label for="address-field">Email Address</label>
<input type="text" name="address-field" id="address-field" required>
</div>
<div class="form-group" id="form-message">
<label for="message-field">Message</label>
<textarea name="message-field" id="message-field" cols="32" rows="8" required></textarea>
</div>
<button id="send-button" type="submit" form="email" name="send-it">Send it</button>
And the CSS:
#email {
display: grid;
grid-gap: 2rem;
grid-template-areas:
"name address"
"message message"
"send send";
grid-template-columns: 1fr 1fr;
justify-items: start;
margin: 1rem auto 0 auto;
width: 80%;
}
#form-name {
grid-area: name;
}
#form-address {
grid-area: address;
}
#form-message {
grid-area: message;
}
.form-group * {
display: block;
}
#form-name, #form-address, #form-message {
width: 100%;
}
#name-field, #address-field, #message-field {
width: 100%;
}
#name-field, #address-field, #message-field {
padding: 0.75rem 1.5rem;
}

Add this to the top of your code
*{
padding: 0px;
margin: 0px;
box-sizing: border-box;
}

#name-field, #address-field, #message-field {
padding: 10px;
}
or 15px if you want it to be close

Related

Keeping row of inputs aligned while adding optional label text above

I have a row of 3 inputs. One of them has label text placed above its input. I do not want this label text to interfere with the alignment of the inputs. Right now I'm using flexbox in my example. My hack/approach is to use position: absolute; on my optional label text to remove it from the flex flow so the inputs stay align. However, this creates a bit of spacing inconsistency when wrapping on smaller viewports. I've tried CSS grid as well but had issues where I was stuck writing a media query for every time I needed to wrap, which seemed worse than this. I would also like the solution to have no fixed widths/heights. As the elements and text can be dynamic. What is the best way to achieve this functionality that allows for a cleaner wrapping?
.container {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.optionalContainer {
position: relative;
/*hack to container optional text*/
padding: 20px 0;
}
.optional {
position: absolute;
top: 0;
margin: 0;
}
<form class="container">
<input required type="text"/>
<div class="optionalContainer">
<p class="optional">Optional:</p>
<input type="text"/>
</div>
<input required type="text"/>
</form>
Example of what I'm shooting for at different viewports:
Here is a solution avoid both positioning and the padding hack using flex with row-gap of the input-height:
:root {
--input-height: 21.2px;
}
.container {
display: flex;
align-items: end;
flex-wrap: wrap;
row-gap: var(--input-height);
}
<form class="container">
<input required type="text" />
<div>
<div>Optional:</div>
<input type="text" />
</div>
<input required type="text" />
</form>
Here is a another solution which avoid both positioning and the padding hack using grid and a grid-template-columns hack:
:root {
--input-width: 146.867px;
--input-height: 21.2px;
}
.container {
display: grid;
/* wrapping hack from https://stackoverflow.com/a/43664701/1248177 */
grid-template-columns: repeat(auto-fill, minmax(var(--input-width), 1fr));
row-gap: var(--input-height);
align-items: end;
}
.optionalContainer > input {
box-sizing: border-box;
width: 100%;
}
<form class="container">
<input required type="text" />
<div class="optionalContainer">
<div class="optional">Optional:</div>
<input type="text" />
</div>
<input required type="text" />
</form>

Why Flex Basis 100% is not working in this case? What is the solution?

I am trying to build a contact form which has fields such as name, phone-number, email, message & submit button. My core agenda is to make Email & message fields acquire 100% width of the contact form. (irrespective of screen size). Name & Phone number fields are responsive & will stay in a single line or go one below the other based on the screen size.
The design is is responsive & have applied flexbox to the .field section & also to .form-container section.
I am applying the flex basis to .w-100 which is not working. By making it flex-basis 100% it should take 100% of container width. But why it is not happing?
What is the mistake I am doing & how to resolve it ?
HTML Section:
<section id="contact" class="contact">
<h2>Contact Me</h2>
<form action="#">
<div class="form-container">
<div class="field">
<label>Name: </label>
<input type="text" placeholder="Name"></input>
</div>
<div class="field">
<label>Phone Number: </label>
<input type="tel" placeholder="Phone Number"></input>
</div>
<div class="field w-100">
<label>Email: </label>
<input type="mail" placeholder="Email"></input>
</div>
<div class="field w-100">
<label>Message: </label>
<textarea cols="30" rows="3"></textarea>
</div>
</div>
<div class="submit-form">
<input type="submit" class="button" value="send" />
</div>
</form>
</section>
CSS Section:
form {
background-color: var(--grey);
padding: 2rem;
border-radius: 1rem;
}
.field {
display: flex;
margin-bottom: 1rem;
}
.field label {
flex: 0 0 90px;
color: var(--white);
}
.field input[type="text"],
.field input[type="tel"],
.field input[type="mail"],
.field textarea {
flex: 1;
}
.w-100 {/*this field not working*/
flex: 0 0 100%;
}
#media(min-width: 768px) {
form {
max-width: 800px;
margin: 0 auto;
}
.form-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.field {
flex: 0 0 calc(50% - 1rem);
}
}
Current Output:
Expected Output:
Thank you #Termani Afif, The property flex: 0 0 calc(50% - 1rem); was overriding in the media query.
This property should be at the bottom for us to get proper output:
.w-100 {
flex: 0 0 100%;
}

html css How to make input field change size without pushing text to next line

How to make input field change size without pushing text to next line?
enter image description here
Easiest way is going to be using display: flex, for more details read Basic concepts of flexbox on MDN.
Getting the labels the right width will require a bit of tweaking on your part, I've used .fieldGroup label { width: 10vw } as a loose value. Best is to use a pixel (px) value which will very much depend on the font family and size
/* BASIC RESET - not relvant to answer */ body { font: 16px sans-serif; margin: 0 }
.fieldGroup {
align-items: center;
display: flex;
gap: 1rem;
}
.fieldGroup:not(:last-of-type) { margin-bottom: 1rem }
.fieldGroup label { width: 10vw }
.fieldGroup input { flex-grow: 1 }
<form style="padding: 2rem">
<div class="fieldGroup">
<label>Name</label>
<input type="text" placeholder="Enter your name…">
</div>
<div class="fieldGroup">
<label>E-mail</label>
<input type="email" placeholder="Enter your e-mail…">
</div>
<div class="fieldGroup">
<label>Really long label here to easily test wrapping</label>
<input type="text" placeholder="???">
</div>
</form>
Use display: flex in CSS
.container {
width: 100px;
}
.flex {
display: flex;
align-items: center;
gap: 5px;
}
<div class="container">
<b>With Flex:</b>
<div class="flex">
<label>Name</label>
<input />
</div>
<br />
<b>Without Flex:</b>
<div>
<label>Name</label>
<input />
</div>
</div>

How can i do my <mat-card> doesn't expand when messages are displayed in Angular 9

I have my <mat-card> that has one form for the login of my page, the problem is when the error messages are displayed they change the size of the <mat-card> vertically and i need it to stay in the same size.
How can i do that?
Below i will let my html file , the sass file of the error messages and pictures of what I have
html file
<div class="bg">
<div class="main-div color ">
<mat-card class="z-depth center col-sm-4 " flex="50" >
<mat-radio-group aria-label="Select an option" [(ngModel)]="radio_btn">
<mat-radio-button [value]="true" >User</mat-radio-button>
<mat-radio-button [value]="false">Admin</mat-radio-button>
</mat-radio-group>
<div class="row justify-content-center " *ngIf="radio_btn==true;else form2">
<form class="example-form " [formGroup]="loginForm" (ngSubmit)="sendUser()">
<mat-form-field class="example-full-width ">
<input matInput formControlName="Identifier" placeholder="Identifier" >
</mat-form-field><br>
<div class=" alert-danger space" *ngIf="identifier.invalid && (identifier.dirty || identifier.touched)">
<div class="container-error-message " *ngIf="identifier.errors.required">
Identifier required
</div>
<div class="container-error-message" *ngIf="identifier.errors.minlength">
Identifier must be at least 7 characters long.
</div>
</div>
<br>
<mat-form-field class="example-full-width">
<input matInput formControlName="Password" placeholder="Password" type="password" >
</mat-form-field><br>
<div class="alert-danger space" *ngIf="password.invalid && (password.dirty || password.touched)">
<div class="container-error-message" *ngIf="password.errors.required">
Password required
</div>
<div class="container-error-message" *ngIf="password.errors.minlength">
Password must be at least 5 characters long.
</div>
</div>
<br>
<button mat-raised-button [class.black]="!loginForm.invalid" [disabled]="loginForm.invalid" type="submit">Sign in</button>
</form>
</div>
<ng-template #form2>
<app-home-admin></app-home-admin>
</ng-template>
</mat-card>
</div>
</div>
SASS file
#import './../../variables_scss/variables.scss';
example-icon {
padding: 0 14px;
}
.example-spacer {
flex: 1 1 auto;
}
.down{
overflow-y: auto;
.colour{
//background: #141519;
background: $orange-bg;
.icons {
color: $black;
}
}
}
.container{
align-items: center;
}
.main-div{
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.center{
width: 75%;
margin: 10px auto;
.mat-radio-button ~ .mat-radio-button {
margin-left: 16px;
}
button {
display: block;
width: 100%;
margin: 2px;
text-align: center;
color: $orange !important;
border-radius: 8px;
}
}
}
.bg{
background: $black;
background: linear-gradient(to right, $dark_black,$light_black );
}
.behind{
z-index: 10;
}
.black {
background-color:$black !important;
}
.space{
margin: $margin-errors;
text-align: $text-align-center;
width: $width-erros;
border: 1px solid;
}
* scss_variables*
$dark_black: #1b1b1b;
$light_black: #424242;
$black: #141519;
$margin-left: auto;
$orange: #fc6407;
$colour_button :$black;
$orange-bg: linear-gradient(to right, #c43e00, #ff6f00);
$margin-errors: 0 auto;
$text-align-center: center;
$width-erros: 180px;
I am not able to replicate your issue with the code given by you. But i would suggest you to provide a constant height to mat-card which is sufficient to enclose all the items. Like i am taking 400px below:
mat-card {
height: 400px;
}
This is how i solve it
Adding this to the space class
max-height: 0px ;
margin-top: 0px !important;
Adding this to the center class
height: 290px;
You can add maximum height and minimum hight of card as same like this in your CSS file , it's worked for me, if you done like this then if the content size is height,automatically scroll will be apply without any size correction
.mat-card{
min-height: 230px ;
max-height: 230px ;
}

How to make element fill remaining width, when sibling has variable width?

In the example below:
I want the textbox to fill all available space. The problem is the dropdown width cannot be fixed, since its elements are not static. I would like to solve this with just css (no javascript if possible).
I have tried the solutions proposed to similar questions without any luck :(
Here is the fiddle: http://jsfiddle.net/ruben_diaz/cAHb8/
Here is the html:
<div id="form_wrapper">
<form accept-charset="UTF-8" action="/some_action" method="post">
<span class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
<option value="1">General</option>
<option value="2">Fruits</option>
<option value="3">Ice Creams</option>
<option value="4">Candy</option>
</select>
</span>
<span class="resizable_text_box">
<input id="question_text_box" name="question[what]" placeholder="Write a query..." type="text" />
</span>
<input name="commit" type="submit" value="Ask!" />
</form>
</div>
And here the css:
#form_wrapper {
border: 1px solid blue;
width: 600px;
padding: 5px;
}
form {
display: inline-block;
width: 100%;
}
.category_dropdown_container {
}
.resizable_text_box {
border: 1px solid red;
}
input[type="text"] {
}
input[type="submit"] {
background-color: lightblue;
width: 80px;
float: right;
}
Updated demo (tested fine in IE7/8/9/10, Firefox, Chrome, Safari)
Float the left and right elements.
In the HTML source code, put both of the floated elements first (this is the most important part).
Give the middle element overflow: hidden; and an implict width of 100%.
Give the text box in the middle element a width of 100%.
.category_dropdown_container {
float: left;
}
input[type="submit"] {
float: right;
...
}
.resizable_text_box {
padding: 0 15px 0 10px;
overflow: hidden;
}
.resizable_text_box input {
width: 100%;
}
<div class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
...
</select>
</div>
<input name="commit" type="submit" value="Ask!" />
<div class="resizable_text_box">
<input id="question_text_box" name="question[what]"
placeholder="Write a query..." type="text" />
</div>
The relatively recent 'flex' display css property solves this problem for you:
All you need to do is change form's display to inline-flex, give .resizable_text_box flex-grow: 100; and give #question_text_box width: 100%
Full example from the OP:
<style>
#form_wrapper {
border: 1px solid blue;
width: 600px;
padding: 5px;
}
form {
display: inline-flex;
width: 100%;
}
.category_dropdown_container {
}
.resizable_text_box {
border: 1px solid red;
flex-grow: 100;
}
#question_text_box {
width: 100%
}
input[type="text"] {
}
input[type="submit"] {
background-color: lightblue;
width: 80px;
float: right;
}
</style>
<div id="form_wrapper">
<form accept-charset="UTF-8" action="/some_action" method="post">
<span class="category_dropdown_container">
<select class="chosen chzn-done" name="question[category_id]" id="selQJK">
<option value="1">Options</option>
</select>
</span>
<span class="resizable_text_box">
<input id="question_text_box" name="question[what]" placeholder="Write a query..." type="text" />
</span>
<input name="commit" type="submit" value="Ask!" />
</form>
</div>
Flex-box lets you do what you wanted to do with css for 15 years - its finally here! More info: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Change some of those <span> elements to <div> elements; then float:left the division around your dropdown; then give the one of the right an overflow:hidden and the input element inside it a width:100%;.
Here's an example. Here it is again with a bigger drop down.
Except that screws up the submit button. So give the #form_wrapper non-static positioning (position:relative) and position the submit button absolutely. See this fiddle and this one.

Resources