Shrink <select> element to fit in nested flexbox - css

I am trying to make some <select> elements shrink to fit horizontally inside a vertical flexbox, with a wrapper around each of them. In the case of the example below, I would like the red box to never extend beyond the select element (dropdown), but the select element should shrink to fit.
The two possibilities I have tried are below: in case 1 the container behaves properly at small scales (the select box shrinks), and in case 2 the red box behaves properly at wide scales (the red box does not grow too wide). Is there a way to combine these behaviours?
div, label {
border: 1px solid black;
margin: 1px;
padding: 1px;
}
.container {
display: flex;
flex-direction: column;
resize: horizontal;
overflow: hidden;
width: 400px;
min-width: 90px;
}
label {
display: flex;
min-width: 0;
flex-direction: row;
border-color: red;
}
.align-stretch { align-self: stretch }
.align-start { align-self: flex-start }
select {
text-overflow: ellipsis;
min-width: 0;
margin: 2px;
}
<div class="container">
<p>Resize this box</p>
<label class="align-stretch">
C1:
<select>
<option>This one is stretchy</option>
</select>
</label>
<label class="align-start">
C2:
<select>
<option>This is start-aligned</option>
</select>
</label>
</div>

Updated solution (fixes the issue of the parent element’s padding):
Use max-width: max-content; and keep the stretch behavior
div,
label {
border: 1px solid black;
margin: 1px;
padding: 1px;
}
.container {
display: flex;
flex-direction: column;
resize: horizontal;
overflow: hidden;
width: 400px;
min-width: 90px;
}
label {
display: flex;
min-width: 0;
flex-direction: row;
border-color: red;
box-sizing: border-box;
}
.align-stretch {
align-self: stretch;
max-width: max-content;
}
select {
text-overflow: ellipsis;
min-width: 0;
margin: 2px;
}
<div class="container">
<p>Resize this box</p>
<label class="align-stretch">
C2:
<select>
<option>This one is stretchy</option>
</select>
</label>
</div>
Original solution: add max-width: 100% to the flex-start case. Note that this does not respect the parent element’s padding.
div, label {
border: 1px solid black;
margin: 1px;
padding: 1px;
}
.container {
display: flex;
flex-direction: column;
resize: horizontal;
overflow: hidden;
width: 400px;
min-width: 90px;
}
label {
display: flex;
min-width: 0;
flex-direction: row;
border-color: red;
box-sizing:border-box;
}
.align-stretch { align-self: stretch }
.align-start { align-self: flex-start; max-width:100%; }
select {
text-overflow: ellipsis;
min-width: 0;
margin: 2px;
}
<div class="container">
<p>Resize this box</p>
<label class="align-stretch">
C1:
<select>
<option>This one is stretchy</option>
</select>
</label>
<label class="align-start">
C2:
<select>
<option>This is start-aligned</option>
</select>
</label>
</div>

Related

i need to change to layout of the buttons and the counter

counter.js
import "./Counter.css";
const Counter = (props) => {
return (
<div className="counter">
<h1>{`Counter ${props.count}`}</h1>
<div className="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
);
};
Counter.css
.counter {
display: flex;
color: white;
align-items: center;
width: 100%;
height: 100%;
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
i want to move the buttons below counter and place the counter and buttons in the center of the page how to change it , display : flex in counter should not be removed
Would something like this work? You can set the flex-direction of a wrapping div to column and set the second div (in your case your buttons) back to flex-direction: row and finally just center it with margin: 0 auto.
<div id="wrap">
<div id="one">1</div>
<div id="two">2
<div id="three">3</div>
<div id="four">4</div>
</div>
</div>
#wrap {
display: flex;
flex-direction: column;
}
#two {
display: flex;
flex-direction: row;
margin: 0 auto;
}
Do you want something like this?
.page {
background: black;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.counter {
display: flex;
flex-direction: column; /* add this */
color: white;
align-items: center;
/* width: 100%;*/
/* height: 100%;*/
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
<div class="page">
<div class="counter">
<h1>Counter 5</h1>
<div class="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
</div>
If so, you can make your whole page a flex container and use justify-content and align-items just like you did it for the .counter.
(I did HTML instead of JSX so I could add the snippet easier... don't forget to make changes in your own code)

Using css ::after to create horizontal dash after input without impacting other elements

using ::after to create a "-" between two inputs. The issue is that I need to move the dash central between the two inputs, I have been trying to do this by adding margin or padding but then that pushes the second input further out which can't happen.
How can I adjust my current code to allow the "-" to move to the left/right without pushing other elements around?
.column {
padding-right: 24px;
padding-left: 24px;
}
.styled-group, styled-group-two {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.styled-group::after {
content: "-";
margin: 0 5px;
height: 1px;
}
.input-two {
width: 45px;
}
.container {
display: flex;
}
<div class="container">
<div class="column">
<div class="styled-group">
<input class="input-one" type="text">
</div>
</div>
<div class="column">
<div class="styled-group-two">
<input class="input-two" type="text">
</div>
</div>
</div>
Codepen: https://codepen.io/simoncunningham/pen/mdwMgyL
If you don't mind giving margin to inputs, this can be handled by absolute positioning.
.styled-group,
styled-group-two {
position: relative;
display: flex;
flex-wrap: wrap;
}
.styled-group input {
margin: 0rem 1rem;
}
.styled-group::after {
content: "-";
position: absolute;
left: 95%;
height: 1px;
}
.input-two {
width: 45px;
}
.container {
display: flex;
}

Mysterious behavior in flex-direction: column

When I write such code, I know that the text does not break.
.a {
display: flex;
border: 1px solid yellow;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
The cause of this problem is that min-width: auto sets the text width of the flex item tomin-width.Therefore, this problem is solved with min-width: 0.
.a {
display: flex;
border: 1px solid yellow;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
min-width: 0; /* add this code! */
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
Next I wrote such a code.
However, the min-width of that code did not work as I expected and a long word overflowed. This is a problem that did not occur at flex-direction: row. What is the cause of this?
Why does min-width: 0 not work in flex-direction: column?
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
align-items: start;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
min-width: 0;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
For flex-direction: row the main-axis is horizontal and the cross-axis is vertical.
For flex-direction: column they switch so the main-axis is vertical and cross-axis is horizontal, you know.
Now let me remind you that
justify-content, flex-grow, flex-shrink and flex-basis properties work on the main-axis
align-items works on the cross-axis
When you set align-items: start you're overriding the default align-items: stretch and your flex-item can take any width which is greater than min-width (as neither width nor max-width are specified).
To achieve the desired behavior it would be enough to remove align-items: start;
min-width: 0 can be also safely removed as it does nothing.
See the snippet below:
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
/* align-items: start; let's use default value instead */
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
/* min-width: 0; this does nothing */
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>
You just need to give div .b an explicit width, or the element will expand to fit content. Using your code, this is as simple as:
.a {
display: flex;
flex-direction: column;
border: 1px solid yellow;
align-items: start;
}
.b {
border: 1px solid green;
overflow-wrap: break-word;
// min-width: 0;
width: 100%;
}
<div class="a">
<div class="b">texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</div>
</div>

Why flexbox not working responsive design with flex-direction?

i have doing my portfolio but i'm not good with CSS.
I'm using the Flexbox to do the design desktop and mobile but it not working...
It is like this, as i want, using flex-direction: column,:
Code of the div parent:
display: flex;
justify-content:center;
align-items:center;
background-color:#C4C4C4;
min-height: 100vh;
flex-direction: column;
But when i put in responsive, it stay like this:
The elements outside of div parent..
The code is the same, only changes the background-color.
background-color: red;
width:800px;
height:650px;
margin: 30px;
It not stay corrects.
If i dont use the flex-direction: column, it stay like this:
Someone why?
Your main issue was missing max-width: 100%; in the children so the width:800px would not overflow the container parent, take a look at the snippet
section {
display: flex;
justify-content: center;
align-items: center;
background-color: #C4C4C4;
min-height: 100vh;
padding: 15px 30px;
box-sizing: border-box;
}
#media(max-width:800px) {
section {
flex-direction: column;
}
}
div {
max-width: 100%;
width: 800px;
height: 650px;
margin: 15px
}
div:first-of-type {
background-color: red;
}
div:last-of-type {
background-color: blue
}
<section>
<div>red</div>
<div>blue</div>
</section>
max-width not set the width of the children elements.
Make sure you set a width to all of your containers; it looks like you want the gray container to fill the viewport, and the blocks to be evenly distributed.
Here's a working example:
.container {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
background-color: gray;
width: 100vw;
height: 100vh;
}
.block {
background-color: #C4C4C4;
min-height: 33vh;
width: 90vw;
}
<div class="container">
<div class="block" style="background-color: red">
A
</div>
<div class="block" style="background-color: blue">
B
</div>
</div>

Making an input and two buttons aligned using SCSS

I want my two buttons, that are actually <a> tags, stick with my input, and be the same size as input. Image perfectly describes what I want to achieve.
Note that I am just starting to learn SASS and CSS. I have tried with this but no luck
NumberInput.js
<div
className="NumberInput"
data-key={dataKey}>
<div className="numberInputField">
<input
data-key={dataKey}
type="text"
name="number"
value={getValue(datakey)}
onChange={onChange(datakey)}/>
</div>
<div className="buttonsField">
<div className="row">
<ValueChangeButton/>
</div>
<div className="row">
<ValueChangeButton/>
</div>
</div>
</div>
NumberInput.scss
$inputMaxWidth: 450px;
$maxHeight: 80px;
$btnFieldMaxWidth: 150px;
.NumberInput{
max-width: $inputMaxWidth;
max-height: $maxHeight;
.numberInputField{
display: inline-block;
text-align: center;
max-width: inherit;
max-height: inherit;
}
.buttonsField{
display: inline-block;
max-width: $btnFieldMaxWidth;
max-height: $maxHeight;
.button{
width: auto;
height: auto;
}
}
}
The result I get is, buttons are contained in their respective rows, but are not the same size as input, and they are flying all around the page. Also, if I change the className of my input, and set the className of its <div> to "numberInputField", it doesn't change its width and height.
Flexbox is perfect for this:
body {
margin: 1em;
}
.NumberInput {
display: flex;
max-width:450px;
margin:auto;
}
.numberInputField {
flex: 3; /* say 3/4 of width */
display: flex;
flex-direction: column;
}
input {
padding: 1em 4em;
flex: 1;
}
.buttonsField {
flex: 1; /* say 1/4 of width */
display: flex;
flex-direction: column;
}
.row {
flex: 1; /* share width equally */
}
a {
width: 100%;
display: block;
background: rebeccapurple;
text-align:center;
text-decoration: none;
font-size: 1.5em;
color: white;
border:1px solid grey;
}
<div class="NumberInput">
<div class="numberInputField">
<input type="submit" />
</div>
<div class="buttonsField">
<div class="row">
↑
</div>
<div class="row">
↓
</div>
</div>
</div>

Resources