Flexbox justify-content depending on number of children - css

Having this:
<label>
<button>Create</button>
</label>
I want button to be aligned to the right like this
----------------------------
| [create]|
----------------------------
while having this:
<label>
<button>Delete</button>
<button>Update</button>
</label>
I want buttons to be in the corners
----------------------------
|[delete] [update]|
----------------------------
Without adding additional classes to the label.

You can just use margin-left: auto on last-child and that will produce desired result.
label {
display: flex;
border-bottom: 1px solid #aaa;
margin: 20px 0;
}
label button:last-child {
margin-left: auto;
}
<label>
<button>Create</button>
</label>
<label>
<button>Delete</button>
<button>Update</button>
</label>

You can do this using nothing but standard flexbox properties:
flex-direction: row-reverse - put the items in a row, start from "the end" (depends on reading direction)
justify-content: space-between - put the items as far away from each other as possible
label {
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
}
<label>
<button>Create</button>
</label>
<label>
<button>Delete</button>
<button>Update</button>
</label>

You can use CSS Flexbox justify-content property to align your elements.
Have a look at this Codepen.
Or look at the code below for reference, also I've used <div>s in place of <label> as in the .two they are acting on both the buttons.
div {
display: flex;
background: #ddd;
padding: 10px 20px;
margin-bottom: 10px;
}
div:first-child {
justify-content: flex-end;
}
div:nth-child(2) {
justify-content: space-between;
}
<div>
<button>Create</button>
</div>
<div>
<button>Delete</button>
<button>Update</button>
</div>
Learn more about CSS Flexbox
Hope this helps!

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>

hide span when data is blank using inline css

my name: [$name]
How to make the “my name:” not visible if the "[$name]" is blank? I’m using inline css because this form will be sent to HTML email.
As mentioned in the comments, if you want to use CSS only, it depends on the HTML structure. It is possible though.
.nameContainer {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
}
.name {
margin-left: 0.5em
}
.name:empty + span {
display: none;
}
<div class="nameContainer">
<span class="name"></span><span>My name:</span>
</div>
<div class="nameContainer">
<span class="name">John Doe</span><span>My name:</span>
</div>

Vertically aligning the button with the TextField in React Material-UI

I am using the Material-UI library for React.
I am trying to make a simple form that looks like:
However, I can't figure out how to align the button with the TextField.
I tried changing the margin-top but it increases the margin of the entire wrapper.
Below is the code sandbox for it.
Any tips on getting this fixed?
https://codesandbox.io/embed/material-demo-y5eg7?fontsize=14&hidenavigation=1&theme=dark
In your styles.css file you can add {position: relative; top: 10px} to the small-button className then adjust the top value until you are happy with the position alternatively you might be able to wrap the row in a div and use {display:flex; flex-direction:row; justify-content:center;} to align them all.
Change the below styles in styles.css
.horizontal-form { /* This is newly added style */
display: flex;
align-items: center;
}
.input-text-wrapper {
/* margin-bottom: 1.2em; */ /* comment these styles */
}
.input-text-wrapper-small {
width: 33%;
/* margin-bottom: 1.2em; */
display: inline-block;
}
.small-button {
width: 10%;
/* display: inline-flex;
align-items: center; */
}
jsx
Remove the small-button div from inside the input-text-wrapper div and Then Enclose the input-text-wrapper div and small-button div inside a newly created horizontal-form div
...
</Typography>
<div className="horizontal-form">
<div className="input-text-wrapper">
<div className="input-text-wrapper-small">
...
</div>
<div className="input-text-wrapper-small">
...
</div>
<div className="input-text-wrapper-small">
...
</div>
</div>
<div className="small-button">
<Button variant="contained" color="primary">
Add
</Button>
</div>
</div>
</CardContent>
....
Just replace this line
<div className="input-text-wrapper">
with
<div className="input-text-wrapper" style={{display:"flex", alignItems:"center"}} >
AND remove margin-bottom from your style.css
.input-text-wrapper-small {
width: 30%;
/*margin-bottom: 1.2em;*/
display: inline-block;
}

Get UIKit - Append form with email address

On UIKit, How do you create an email form with an inline text so the user can input text and the form has #example.com after it.
You can do this in bootstrap here: https://getbootstrap.com/docs/4.0/components/input-group/
But I am unable to recreate this on UiKit?
Just "borrow" the concept from bootstrap. Wrap the elements within grid, group them with the class name, and inside the group add element with the flexbox display, it will fit automatically. From what I've seen in sources - they give him 1% width - maybe there's a case for that, but anyway works with only display:flex.
Here's my proposition:
HTML
<form class="uk-grid-small" uk-grid>
<div class="uk-width-1-2#s input-group">
<input class="uk-input" type="text" placeholder="50">
<div class="input-group-append">
<div class="input-group-text">
#email
</div>
</div>
</div>
</form>
CSS
.input-group {
display: flex;
}
.input-group-append {
display:flex;
align-items:center;
}
.input-group-text {
display: flex;
align-items: center;
font-weight: 400;
height:38px;
color: #495057;
padding: 0 10px 0;
text-align: center;
white-space: nowrap;
background-color: #e9ecef;
border: 1px solid #ced4da;
border-left:none;
}
I've also made a codepen for the reference https://codepen.io/arysom/pen/QzGjyo

Input size being disregarded and being set to 100% of parent element

Input size seems to disregard the size attribute and instead set a width of 100% to the parent element.
Css:
.lespan {
display: flex;
flex-direction: column;
justify-content: flex-end;
background: red;
min-width: 300px;
input {
min-width: 0px;
size: 5;
}
}
input {
min-width: 0px;
size: 5;
}
html:
<span class="lespan">
hello
<input type="text">
</span>
<input type="text">
Codepen: https://codepen.io/basickarl/pen/Lybvyz
I'd like both inputs to be of size 5.
You are pointing the wrong problem.
Stop using invalid property values.
Size is attribute and attribute belong to HTML. Set input size attribute with CSS?
Always inspect your code in browser.
If you want set size, then set the width of input.
.lespan {
display: flex;
flex-direction: column;
justify-content: flex-end;
background: red;
min-width: 300px;
}
input {
width: 100px;
}
<span class="lespan">
hello
<input type="text" >
</span>
<input type="text">
size is not a valid css atribute, but a html attribute. You may want to set them like so:
<input type="text" size="5">
Also, display:flex will break the size attribute value of the input, you might want to use display:block, use the css width attribute instead of size or change the html structue so that the input element is outside of a container with display:flex
Moreover, You can't nest styles, to apply a specific style to an element using both its tag name and a class name you might want to try something like this:
input.lespan {
min-width: 0px;
size: 5;
}
Just add align-items: flex-start; to .lespan. Here is the updated CodePen
.lespan {
display: flex;
flex-direction: column;
justify-content: flex-end;
background: red;
min-width: 300px;
align-items: flex-start;
}
.lespan input {
min-width: 0px;
size: 5;
}
input {
size: 5;
}
<span class="lespan">
hello
<input type="text">
</span>
<input type="text">
You can use css width property:
input{
width:200px;
}
Or html
<input type="text" size="5">

Resources