Flex box not working - html

I am developing a web app with meteor and material design lite.
Here is what I want to do :
Here is the result with a too small window :
And here is the result with a bigger window :
The HTML code :
<template name="myRefrigerator_header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">My Refrigerator</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
</div>
<!-- Simple Textfield -->
<div id="msg-layout">
<form action="#">
<div class="mdl-textfield mdl-js-textfield" id="msg-layout-content">
<input class="mdl-textfield__input" type="text" name="content">
<label class="mdl-textfield__label" for="sample1">Text...</label>
</div>
<button class="mdl-button mdl-js-button mdl-button--primary"
id="msg-layout-add-button">
Enregistrer
</button>
</form>
</div>
</header>
</template>
And the CSS applied to it :
#msg-layout {
background-color: #F5F5F5;
margin: 0px 25px 15px 25px;
padding-left: 10px;
padding-right: 10px;
display: flex;
flex-direction: row-reverse;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: stretch;
}
#msg-layout-content {
color: #3F51B5;
flex: 1 1 0;
}
#msg-layout-add-button {
}
I don't understand why I don't have the right behavior, I have specified that I only want one row and that my input should resize.
What am I getting wrong ?

First, you need to give the id="msg-layout" to the <form>. Only direct children of a display:flex layout will get the special attributes of flexible containers. You are negating flexbox by nesting a <form> where the flexible children would be. Your flexible layout only has one child, the <form>.
This is the best resource I have found for learning flex-box https://css-tricks.com/snippets/css/a-guide-to-flexbox/

I would suggest trimming things down. Flex-box isn't the problem, and more that libraries of style rules make a lot of assumptions - that you may not be able to see from the top.
Here is a stripped down version / http://codepen.io/sheriffderek/pen/MKzMgp
HTML
<form class='this-form' action='#'>
<label class='input-w' for='sample1'>
<input type='text' id='sample1'>
<span>Text...</span>
</label>
<button>Enregistrer</button>
</form>
SCSS
* { // reset box model
box-sizing: border-box;
}
.this-form {
display: flex; // a
flex-direction: row; // b
align-items: center; // d
max-width: 24rem;
padding: .5rem;
border: 1px solid blue;
.input-w {
position: relative;
flex-grow: 1; // c
input {
width: 100%;
border: 0;
border-bottom: 1px solid gray;
&:focus {
outline: none;
+ span {
transform: translate(0, -50px);
opacity: 0;
}
}
}
span {
position: absolute;
bottom: 3px;
left: 0;
color: gray;
font-size: 12px;
transition: 1s;
}
}
button {
height: 30px;
background: transparent;
border: 0;
color: blue;
margin-left: .5rem;
}
}

The mdl-textfield__input class has a set width of 300px due to animation limitations. You need to override this (say width: 100%) to get an expandable textfield. However, this may have adverse affects on the animations since CSS animations don't like unknown lengths.

Related

How do I get flex elements not to grow on click?

Hobbyist who really sucks at css.
I have the following three divs:
The problem is, when I click on the middle one, the box grows, and so do the other two boxes:
How do I make boxes start off and stay the same size even after click. The reason the box is growing is do to adding the "arrow-icon"
Code looks like this:
HTML
<section class='modes-flex__options'>
<div class='options'>
<h2 class='options__title'>Options</h2>
<div class='options__item-container'id='1v1' onClick="selectedGameOption(this.id)">
<h3 class='options__item'>Player vs AI (1 v 1) </h3>
<div class='arrow-icon__div'>
<i></i>
</div>
</div>
<div class='options__item-container' id='1v1-tourny' onClick="selectedGameOption(this.id)">
<h3 class='options__item'>Player vs AI (Tournament)</h3>
<div class='arrow-icon__div'>
<i></i>
</div>
</div>
<div class='options__item-container' id='ai-v-ai-tourny' onClick="selectedGameOption(this.id)">
<h3 class='options__item' >AI vs AI (Tournament)</h3>
<div class='arrow-icon__div'>
<i></i>
</div>
</div>
</div>
</section>
CSS
.modes-flex{
display: flex;
margin-top: 3rem;
&__options{
flex:1;
display: flex;
justify-content: end;
}
&__description{
flex:1;
display: flex;
flex-direction: column;
}
}
.options{
margin-right: 5rem;
&__title{
font-size: 1.2rem;
padding-bottom:2rem;
}
&__item{
flex: 1;
padding-right: 5rem;
}
}
.description{
&__title{
font-size: 1.2rem;
padding-bottom:2rem;
}
}
.options__item-container {
padding: 1.5rem 1rem 1.5rem 1rem;
margin-bottom: 2rem;
box-shadow: 0 0 10px lightgrey;
border: 1px solid lightgrey;
display: flex;
align-items: center;
&:hover{
cursor: pointer;
}
}
.arrow-icon__div{
text-align: right;
}
.active-option{
background-color: $dark-navy;
color: white;
}
Tried to set min and max width and was still growing , just want them to stay even width after adding the icon.
You said it: The reason the box is growing is do to adding the "arrow-icon".
In my experience, in these situations, I always added to the default size of the boxes so that when another element (i.e. arrow-icon) is added, it doesn't change the size. (Because there is enough space in the box for arrow-icon to be added). With doing so, all the boxes remain the same through any actions.

How to not shink the white background field when no text or having only the white space

I don't know that how to expand the span background color if there is on text inside like this.
I want the white background with on text to remain the same size as white background with text.
My CSS
.dashboard-data-field {
display: grid;
grid-auto-flow: row;
align-content: center;
}
.dashboard-data-header {
padding: 4px;
}
.dashboard-data-description {
padding: 8px;
background-color: #fff;
}
My JavaScript
<div className="dashboard-data-field">
<span className="dashboard-data-header">ชื่อ-นามสกุล</span>
<span className="dashboard-data-description">{`${auth.user.firstname} ${auth.user.lastname}`}</span>
</div>
You could try two different solutions:
Adding a as the content of the html element when it's
supposed to be empty.
Or you could add the css style attribute min-height: 1em; in the rules addressing header and description. (I corrected this part compared to what I wrote before)
I picked the second option here because consistent with css font-size arbitrarily chosen and doesn't require you to modify the logic to fill the contents adding a non blank space when it's empty:
.dashboard-data-field {
display: grid;
grid-auto-flow: row;
align-content: center;
/*the field background is yellow to get contrast with the description bg*/
background-color: yellow;
}
.dashboard-data-header {
display: block;
padding: 4px;
/*this shows the size of the header*/
border: solid 1px red;
/*minimum height is 1em even when the content is empty*/
min-height: 1em;
}
.dashboard-data-description {
display: block;
padding: 8px;
/*this background will cover the parent background*/
background-color: #fff;
/*this shows the size of the header*/
border: solid 1px red;
border-top: none;
/*minimum height is 1em even when the content is empty*/
min-height: 1em;
}
<div class="dashboard-data-field">
<span class="dashboard-data-header">Header with content</span>
<span class="dashboard-data-description">Description with content</span>
</div>
<br>
<div class="dashboard-data-field">
<span class="dashboard-data-header"></span>
<span class="dashboard-data-description"></span>
</div>
Give fixed height to span from where you wanna show text
.dashboard-data-field {
display: grid;
grid-auto-flow: row;
align-content: center;
}
.dashboard-data-header {
padding: 4px;
}
.dashboard-data-description {
padding: 8px;
background-color: red;
height: 40px;
}
const App = () => {
return (
<>
<div className="dashboard-data-field">
<span className="dashboard-data-header">ชื่อ-นามสกุล</span>
<span className="dashboard-data-description">with text</span>
</div>
<div className="dashboard-data-field">
<span className="dashboard-data-header">ชื่อ-นามสกุล</span>
<span className="dashboard-data-description"></span>
</div>
</>
);
};
export default App;

Is Angular adding margin/padding to my component?

I'm facing a little problem.. I'm trying to build some kind of "Matrix" to build a snake game in angular, and for some reason, there is a margin / padding I can not remove. Here is my code:
<!-- snake.component.html -->
<div id="ng-snake-main">
<div *ngFor="let row of matrix" class="row">
<ng-container *ngFor="let box of row.boxes>
<snake-box [box]="box"></snake-box>
</ng-container>
</div>
</div>
<!-- box.component.html -->
<div class="box"></div>
Both using the same style file:
// styles.scss
.row {
margin: 0px;
padding: 0px;
}
.box {
display: inline-block;
background-color: blue;
width: 30px;
height: 30px;
border: 1px solid black;
}
so, why is there a space between rows??? I think that it doesn't make sense, but I'm sure I'm missing something. I'll left some screenshots:
In this screenshot you can check that the "snake-box" component is adding some kind of margin.
In this other screenshot you can see that the div actually doesn't have margin/padding.
Is angular adding margin to my component? If yes, how can I remove it?
The answer to you problem is CSS FLEX.
It would work with these styles:
// styles.scss
.row {
display: flex;
flex-direction: row;
}
.box {
background-color: blue;
width: 30px;
height: 30px;
border: 1px solid black;
}
If you want more information about flexbox, here is an interesting link https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Vertically align the text of an input element

I've had a bit of an issue with some flex containers. They're a label and an input in a flex container. Unfortunately, if I change the height of the container from auto, the contents cease aligning - the label's text remains at the start of the flexbox, but the input's text follows the middle. I've written a MWE to demonstrate.
label, input {
border-style: solid;
border-width: 2px;
border-color: red;
background-color: black;
}
.stretch {
display:flex;
height: 4em;
}
.baseline {
display: flex;
height: 4em;
align-content: baseline;
}
.flex-innards {
display: flex;
height: 4em;
align-content: stretch;
}
.flex-innards * {
display: flex;
align-items: center;
}
.flex-innards-start {
display: flex;
height: 4em;
align-content: stretch;
}
.flex-innards-start * {
display: flex;
align-items: flex-start;
}
.short {
height: auto;
}
<div class="stretch">
<label>Stretch alignment</label>
<input value=":("></input>
</div>
<div class="baseline">
<label>How about baseline?</label>
<input value=">:("></input>
</div>
<div class="flex-innards">
<label>Flexing the children kinda works</label>
<input value=":o"></input>
</div>
<div class="flex-innards-start">
<label>But only if they're centered</label>
<input value=":("></input>
</div>
<div class="field short">
<label>Deceptive stretch</label>
<input value=":S"></input>
</div>
https://jsbin.com/nulobolulo/edit?html,css,output.
I've managed to make them vertically centered together in the third box there (using How to vertically align and stretch content using CSS flexbox), but I'd like to have them both have their text aligned to flex-start, as well as filling the complete height of their container.
If possible, I'd like to avoid adding extra elements to the HTML. Thank you.
I think the only way to address this problem with CSS uses the padding property.
input {
padding-bottom: 40px;
}
label,
input {
border-style: solid;
border-width: 2px;
border-color: red;
}
.stretch {
display: flex;
height: 4em;
}
<div class="stretch">
<label>Stretch alignment</label>
<input value=":(">
</div>

Unable to center the elements [duplicate]

This question already has answers here:
How can I horizontally center an element?
(133 answers)
Closed 2 years ago.
So, I am new at coding. I was trying to make a very basic static webpage of a calculator using html and css and js.
This is the html
#input {
margin: 0 auto;
}
#num {
border-radius: 25px;
background: #73AD21;
display: inline-block;
padding: 15px;
width: 200px;
height: 100px;
}
<body>
<div id="input">
<div id="num">
<label for="num1">Enter the first number</label>
<input type="number" name="num1" id="num1">
</div>
<div id="num">
<label for="num2">Enter the second number</label>
<input type="number" name="num2" id="num1">
</div>
</div>
<div id="op">
<div id="opadd"><input type="submit" name="add" class="add" value="Add" onclick="add()"></div>
<div id="opsbtrct"><input type="submit" name="subtract" class="sbtrct" value="Subtract" onclick="sbtrct()"></div>
<div id="opmult"><input type="submit" name="multiply" class="mult" value="Multiply" onclick="mult()"></div>
<div id="opdvde"><input type="submit" name="divide" class="add" value="Divide" onclick="dvde()"></div>
</div>
</body>
I want that the #num be centered horizontally.
I tried using
margin: auto;
and
margin: 0 auto;
but nothing works. Please help.
I've been at it for hours.
Here is the complicated way of doing this.
You should create a container div, so you can center the object in.
#container {
display: flex; /* establish flex container */
flex-direction: row; /* default value; can be omitted */
flex-wrap: nowrap; /* default value; can be omitted */
justify-content: space-between; /* switched from default (flex-start, see below) */
background-color: lightyellow;
}
#container > div {
width: 100px;
height: 100px;
border: 2px dashed red;
}
<div id="container">
<div></div>
<div></div>
<div></div>
</div>
when you add margin: 0 auto be sure the html tag not inline or inline-block it should be 'block' css with specific width.
#num {
border-radius: 25px;
background: #73AD21;
display: block;
padding: 15px;
width: 200px;
height: 100px;
margin: 1em auto;
}
label{
white-space: nowrap;
}
just replace this code hope your problem will fix.
add white-space:nowrap for the label to use one line text. #num should be 'block' css with specific width like 200px and display block. thanks