Making an input and two buttons aligned using SCSS - css

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>

Related

CSS ignores width of children when using aspect ratio

I have encountered an issue regarding CSS's aspect-ratio on child elements.
I've been trying to style an element's width and height (both the same) to be equal to the height of the parent container. Using height: 100%; and aspect-ratio: 1; makes this work, however;
It seems the parent container ignores the children's resized width when using aspect-ratio, meaning the parent container ends up with the wrong width.
I've included a codepen illustrating the issue. Notice how the width does increase with each new element, but the width increase does not correspond to the actual width of the added elements.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
padding: 8px;
}
.container {
border: 1px solid red;
display: flex;
flex-direction: row;
align-items: stretch;
column-gap: 16px;
width: fit-content;
}
.button_container {
display: flex;
column-gap: 8px;
border: 1px solid green;
width: fit-content;
}
.button {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
}
.first_case {
height: 100%;
aspect-ratio: 1 / 1;
}
.second_case {
height: 100%;
width: 56px;
}
<p>Fixed width (this is how it should look)</p>
<div class="container">
<div>
Text<br/>More text<br/>Lots of text
</div>
<div class="button_container">
<div class="button second_case">
A
</div>
<div class="button second_case">
B
</div>
</div>
</div>
<p>Aspect ratio</p>
<div class="container">
<div>
Text<br/>More text<br/>Lots of text
</div>
<div class="button_container">
<div class="button first_case">
A
</div>
<div class="button first_case">
B
</div>
</div>
</div>
https://codepen.io/th3o4or/pen/ZEoqMrm

How to center a horizontally scrollable div, without cutting off the first element?

Note: NOT a duplicate of :
Flexbox displays divs incorrectly rather than making the container scrollable
Can't scroll to top of flex item that is overflowing container
My use-case attempts to center the overflowing items. Solutions acknowledge this limitation, without solving it. (Their items are not centered)
Imagine if Netflix presented their choices with the middle item positioned in the center of the screen. That's the effect I'm going for with my columns sroller, but my first item is partially cut off. I found a solution on SO using jQuery, but I'd rather wrestle CSS into submission. Need to tag one of you in though... got any ideas?
* {
font-family: sans-serif;
}
.options-wrapper {
font-size: 3vw;
text-align: center;
}
.options-wrapper .options-visualized {
display: flex;
flex-wrap: nowrap;
overflow-x: scroll;
justify-content: center;
margin: 0 auto;
}
.options-wrapper .options-visualized .option {
flex-basis: 40vw;
flex-shrink: 0;
margin: 0 8vw;
display: flex;
flex-direction: column;
}
.options-wrapper .options-visualized .option:first-of-type {
margin-left: 2vw;
}
.options-wrapper .options-visualized .option:last-of-type {
margin-right: 2vw;
}
.options-wrapper .options-visualized .option img {
width: 100%;
margin: 0 auto;
}
.options-wrapper .options-visualized .option .option-label {
margin-top: 1em;
flex-basis: 100%;
font-size: 0.92em;
line-height: 1.25;
}
.options-wrapper .options-visualized .option .option-label span {
display: block;
}
<div class="options-wrapper graded-bg">
<h6 class="options-title">options:</h6>
<div class="options-visualized">
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 1</span></div>
</div>
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 2</span></div>
</div>
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 3</span></div>
</div>
</div>
</div>
Here's a pen: https://codepen.io/sashaikevich/pen/yLgbWQx
I just edited &:last-of-type to be like this :
&:last-of-type {
margin-right: -56vw;
}
Try this Example to know what I mean :
https://codepen.io/kevinmmansour/pen/VwPrJGw

Align text of different size to the bottom

I have two divs with text of different sizes, that I want to align to the bottom.
They do successfully get aligned to the bottom of their parent, but they're not aligned evenly to each other.
Is this solvable?
.container {
display: flex;
height: 50px;
background: pink;
}
.large, .small {
align-self: flex-end;
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="large">Large</div>
<div class="small">Small</div>
</div>
One way would be to put both text DIVs into another wrapper (.inner_container in my snippet below) which gets the settings the texts previously had in order to align to the bottom, and apply display: inline-block; to the text DIVs: inline-blocks align to each other by their baseline by default, which is what you want if I understand correctly:
.container {
display: flex;
height: 50px;
background: pink;
}
.inner_container {
align-self: flex-end;
}
.large,
.small {
display: inline-block;
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="inner_container">
<div class="large">Large</div>
<div class="small">Small</div>
</div>
</div>
As per #Johannes answer it's a good idea to wrap both text divs in another container. But you don't need an align-self: flex-end; declaration for the .inner-container, just add align-items: flex-end; to the parent div. That way, you get one CSS rule less.
display: inline;, like display: inline-block, makes items align themselves by their baselines (based on the item with the biggest height, in this case the .large text) so you could change the <div class="large"> and the <div class="small"> to spans instead of divs. Since the default display property of <span> is inline, you can then skip the display declaration of .large and .small:
.container {
display: flex;
height: 50px;
background: pink;
align-items: flex-end;
}
.large, .small {
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="inner-container">
<span class="large">Large</span>
<span class="small">Small</span>
</div>
</div>

CSS - Horizontally and vertically distribute divs

So I've got this header with three elements in them.
What I want is basically this:
http://jsfiddle.net/zktbfmqo/2/
Only with vertically centered content in each of the divs as well.
Is there an easy and clever way to do this without using absolutes etc?
Vertical-align: middle doesn't seem to do much, but that property isn't always easy to work with either.
HTML:
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
CSS:
#container {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 612px;
}
.box1, .box2, .box3 {
width: 150px;
height: 125px;
vertical-align: middle;
display: inline-block;
*display: inline;
zoom: 1;
text-align: center;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0
}
First you can achieve the same result in a better way by using Flexbox.
For vertical align text to the middle you can simply approach that by adding the line-height property and set it to the same exact height of the container div so in your case it would be 125px or if you used flexbox it can be done with align-items: center , and here is the final code:
.wrapper {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row nowrap; /* Safari 6.1+ */
flex-flow: row nowrap;
-webkit-justify-content: space-between; /* Safari 6.1+ */
justify-content: space-between;
font-weight: bold;
height: 125px;
min-width: 612px;
padding: 5px;
border: 2px dashed #444;
}
.wrapper > div{
display: -webkit-flex;
display: flex;
-webkit-flex-basis: 150px;
flex-basis: 150px;
justify-content: center;
align-items: center;
}
.aside-1, .aside-3{
background: #ccc
}
.aside-2{
background: #0ff;
}
<div class="wrapper">
<div class="aside aside-1">text1</div>
<div class="aside aside-2">text2</div>
<div class="aside aside-3">text3</div>
</div>
Flexbox to the rescue!
Good resources:
https://philipwalton.github.io/solved-by-flexbox/
https://github.com/philipwalton/flexbugs
#container {
display: flex; /* magic maker */
justify-content: space-between; /* set equal space between boxes */
border: 2px dashed #444;
height: 125px;
/* just for demo */
min-width: 612px;
}
.box1, .box2, .box3, .box4 {
display: flex; /* magic maker */
/*
shorthand for flex-grow, flex-shrink, and flex-basis properties
we don't want the boxes to grow or shrink, and the basis is the explicit
width we want them
*/
flex: 0 0 150px;
justify-content: center; /* horizontally center text within */
align-items: center; /* vertically center text within */
height: 125px;
}
.box1, .box3 {
background: #ccc
}
.box2, .box4 {
background: #0ff
}
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
</div>
you can use display:table/table-cell and using a workaround with border-collapse/spacing + margin you will get the desired output.
#wrap {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
overflow:hidden;
/* just for demo */
width: 612px;
}
#container {
margin: 0 -81px; /*must be equal to border-spacing */
}
#table {
display: table;
table-layout: fixed;
border-collapse: separate;
border-spacing: 81px 0;
width: 100%;
}
.box1,
.box2,
.box3,
.box4 {
width: 150px;
height: 125px;
vertical-align: middle;
display: table-cell;
text-align: center;
}
.stretch {
width: 100%;
vertical-align: middle;
display: table-cell;
}
.box1,
.box3 {
background: #ccc
}
.box2,
.box4 {
background: #0ff
}
<div id="wrap">
<div id="container">
<div id="table">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
</div>
</div>
Are you familiar with Bootstrap?
It is a CSS Framework made by Twitter.
Put this inside of your head -
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
Use this in your body to see what it does, there's great docs on it.
<div class="container"> <!-- Creates margin -->
<div class="row"> <!-- Read docs on rows, they're awesome! -->
<div class="col-lg-4"> <!-- 1 -->
<!-- Just to take up space -->
</div>
<div class="col-lg-4"> <!-- 2 -->
<!-- YOUR CONTENT GOES HERE -->
</div>
<div class="col-lg-4"> <!-- 3 -->
<!-- Just to take up space -->
</div>
</div> <!-- ./row -->
</div> <!-- ./container -->
Now inside of the 2nd ./col-lg-4 div all of that content will be perfectly centered in the screen with the text aligned left.
If you want to align center the text, replace
<div class="col-lg-4"> <!-- 2 -->
with
<div class="col-lg-4 text-center"> <!-- 2 -->
Hope this helps!

How to use css3 'flexbox' to make a layout like this?

Here is a div container. I know how to easily use display and width to make it look like this, but how to use CSS3 flexbox to make 4 buttons layout as follow?
.container {
background-color: blue;
width: 200px;
padding: 10px;
}
button {
display: block;
width: 100%;
}
button:nth-of-type(2),
button:nth-of-type(3) {
width: 49%;
display: inline;
}
<div class="container">
<button>Button1</button>
<button>Button1</button>
<button>Button1</button>
<button>Button1</button>
</div>
Use flex-flow:row wrap and make the top / bottom buttons take twice the space
div, div *{box-sizing:border-box;}
div{display:flex;flex-flow:row wrap;padding:50px;}
div button{flex:1;}
div button:first-child,
div button:last-child{flex:2 100%}
<div>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
HTML
<div class="container">
<button>Button1</button>
<button>Button2</button>
<button>Button3</button>
<button>Button4</button>
</div>
CSS
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: blue;
width: 200px;
padding: 10px;
}
button { margin: 5px 0; }
button:nth-of-type(1),
button:nth-of-type(4) { flex: 1 1 100%; }
button:nth-of-type(2),
button:nth-of-type(3) { flex: 0 1 45%; }
DEMO

Resources