How to control the size of <label> element in React? - css

I want to make element to be the same size of box, but the size of label is shorter than I expected. Also, "width" is not working in the React.
How can I solve this problem?
const DragDrop = () => {
...
return (
<div className="DragDrop" style={{ height: `${30 + 5 * files.length}vh` }}>
<input
type="file"
accept="audio/flac, audio/mp3, audio/ogg, audio/wav"
id="fileUpload"
style={{ display: "none" }}
multiple={true}
onChange={onChangeFiles}
/>
<div className={isDragging ? "DragDrop-File-Dragging" : "DragDrop-File"}>
<label htmlFor="fileUpload">
<Box ref={dragRef} className={"DragDrop-FileBox"}>
<Typography variant="h5">
{isDragging
? "Drop here!"
: "Drag files"}
</Typography>
</Box>
</label>
</div>
</div>
);
};
This code shows example like this.
If I remove element, the result shows like this. (just I expected.)
And here is scss file I used.
#mixin filledStyle() {
background-color: grey;
border-radius: 10px;
color: white;
}
#mixin alignCenter() {
display: flex;
display: -webkit-flex;
flex-direction: column;
-ms-flex-direction: column;
align-items: center;
}
#mixin alignCenterVertical() {
display: flex;
display: -webkit-flex;
flex-direction: column;
-ms-flex-direction: column;
justify-content: center;
align-items: center;
}
.DragDrop {
width: 100%;
height: 20vh;
#include alignCenter();
&-File {
width: 100%;
height: 200px;
border: 2px dashed grey;
border-radius: 10px;
#include alignCenterVertical();
cursor: pointer;
transition: 0.12s ease-in;
&-Dragging {
width: 100%;
#include filledStyle();
}
}
&-FileBox {
width: 100%;
height: 200px;
border: 2px dashed grey;
border-radius: 10px;
#include alignCenterVertical();
cursor: pointer;
transition: 0.12s ease-in;
}
}

Make forcefully take the label width 100% via width 100% in the label
.DragDrop {
width: 100%;
height: 20vh;
#include alignCenter();
label{
width:100%;
}
}

It seems <label> elements are inline, by default (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label).
inline elements can have neither width nor height (ignored).
Set display: inline-block to overcome this problem.

Related

border-radius style property not rounding the edges in reactjs

I want the edges of the div c-thumbnail__container to be rounded, but it is not working at all. Is there a way to do this?
const Thumbnail = () => {
const [isShown, setIsShown] = useState((false));
return (
<>
<div className='c-thumbnail__container' onMouseEnter={() => setIsShown(true)} onMouseLeave={() => setIsShown(false)}>
<img src={example} alt="Thumbnail" />
<Bookmark onClick={onClickBook}/>
{isShown && (
<BtnPlay />
)}
</div>
</>
)
}
.c-thumbnail__container{
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
min-width: 164px;
min-height: 110px;
}
.c-thumbnail__container:hover{
cursor: pointer;
filter: brightness(.7);
}
To add a border radius, you have to add the border-radius property to the elements CSS. It looks like you have forgotten to do that.
This CSS will fix your problem:
.c-thumbnail__container{
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
min-width: 164px;
min-height: 110px;
// added:
border-radius: 10px;
}
.c-thumbnail__container:hover{
cursor: pointer;
filter: brightness(.7);
}
Learn more about border-radius at https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius

Trying to make a panning window with CSS

I'm trying to make a window that will display a number of show listings, panning through each with left and right scroll buttons. The problem is, when I place two listing layouts within the frame, it doesn't add them side by side at their full size with a scrollbar as I would expect. Instead, it distorts both so they will fit in the same space.
EDIT: I thought it might be prudent to mention that the ultimate goal here is to get a list of show objects from a server, and the number can vary. So, the width of the div holding them will have to adapt to the change.
Here is what I'm after, with one in view:
Here is what is actually happening:
The color gradient is only there so I can see what I'm doing. Once I'm sure they're panning correctly, it'll be changed to transparent. Below is my code. If anyone can offer any advice, I'd appreciate it.
Shows.js:
import {useState} from 'react';
import styles from './Shows.module.css';
const Shows = () => {
const Show = (details) => {
return (
<div className={styles.showMain}>
<div className={styles.posterFrame} style={null /* SET BACKGROUND IMAGE HERE, COVER??? */}/>
<div className={styles.textFrame}>
TEST
</div>
</div>
)
}
return (
<div className={styles.main} id="shows">
<div className={styles.container}>
<div className={styles.banner}>
<h1 className={styles.bannerText}>UPCOMING SHOWS</h1>
</div>
<div className={styles.scrollContainer}>
<div className={styles.scrollButton}><</div>
<div className={styles.showBody}>{Show(null)}</div>
<div className={styles.showBody}>{Show(null)}</div>
<div className={styles.scrollButton}>></div>
</div>
</div>
</div>
)
}
export default Shows
Shows.module.css:
.main {
display: flex;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), linear-gradient(112.78deg, rgba(183, 35, 35, 0.5) 12.87%, rgba(51, 169, 236, 0.5) 52.53%, rgba(74, 183, 35, 0.5) 97.84%), url("../../public/images/concert1.jpg");
background-size: cover;
height: 100vh;
width: 100vw;
justify-content: center;
align-items: center;
}
/* ---------------- Scrolling frame ---------------- */
.container {
position: relative;
display: flex;
flex-direction: column;
background: rgba(0,0,0,.5);
height: 82.5%;
width: 85%;
margin-top: 6%;
}
.scrollContainer {
display: flex;
flex-direction: row;
height: 90%;
width: 100%;
overflow: hidden;
}
.banner {
background: rgba(0,0,0,0.45);
display: flex;
height: 10%;
width: 100%;
align-items: center;
justify-content: center;
}
.bannerText {
font-weight: lighter;
color: rgba(50, 236, 191, 1);
text-shadow: 2px 2px rgba(183, 35, 35, 1);
}
.scrollButton {
display: flex;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.25);
color: white;
height: 100%;
width: 5%;
transition-duration: .25s;
}
.scrollButton:hover {
background: rgba(0,0,0,0.45);
}
.showBody {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.25);
height: 100%;
width: 90%;
overflow: hidden;
}
/* ---------------- Show listing ---------------- */
.showMain {
height: 100%;
width: 100% !important;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: linear-gradient(90deg, #FF0000 -9.27%, rgba(34, 255, 0, 1) 112.68%);
overflow: hidden;
}
.posterFrame {
height: 90%;
width: 35%;
background: rgba(0,0,0,0.65);
margin-right: 5%;
}
.textFrame {
height: 90%;
width: 50%;
background: rgba(0,0,0,0.65);
color: white;
}
.scrollContainer {
display: flex;
flex-direction: row;
height: 90%;
width: 100%;
overflow: hidden;
}
This not going to work, you need make it like so:
.scrollContainer {
display: flex;
flex-direction: row;
height: 90%;
//width: 100%; < wrong
//overflow: hidden; < wrong
overflow-x:auto;
flex-wrap:no-wrap;
}
Then
.showMain {
height: 100%;
//width: 100% !important;
width: 300px; // sorry I have to be specified
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: linear-gradient(90deg, #FF0000 -9.27%, rgba(34, 255, 0, 1) 112.68%);
overflow: hidden;
}
Alright, I figured it out. In combination with the suggestions here, which got me to the side by side display I was after, I placed the two Show items in a new div with the className showWindow. I set the CSS for the window as follows:
.showWindow {
width: 90%;
display: flex;
flex-direction: row;
overflow: auto;
}
This displays one at a time, gives me the scrollbar, and does not obstruct the scroll buttons. Thanks for helping me find the solution, everyone.
Update the css:
.scrollContainer {
...
overflow: auto;
}
.showBody {
...
flex: none;
}
.scrollButton {
...
flex: none;
}
.sliderContainer {
display: flex;
height: 100%;
}
Then wrap the content with a sliderContainer:
<div className={styles.sliderContainer}>
<div className={styles.scrollButton}><</div>
<div className={styles.scrollContainer}>
<div className={styles.showBody}>{Show(null)}</div>
<div className={styles.showBody}>{Show(null)}</div>
</div>
<div className={styles.scrollButton}>></div>
</div>
And it works fine.

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)

Shrink <select> element to fit in nested flexbox

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>

Unable to target nth child of styled component

I'm trying to target 3 children divs of a styled component, and I can't figure out what I'm doing wrong with my syntax, and the styled component docs don't seem to cover this well. My code is:
const HamburgerButton = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
min-height: 60%;
min-width: 50px;
border-radius: 8px;
&:nth-child(1){
width: 32px;
min-height: 3px;
background-color: red;
}
&:nth-child(2){
width: 32px;
min-height: 3px;
background-color: red;
}
&:nth-child(3){
width: 32px;
min-height: 3px;
background-color: red;
}
`
const MobileNav = () => {
const [open, setOpen] = useState(false)
return (
<MobileNavContainer>
<Name>
<h1>Josh Bangle</h1>
</Name>
<HamburgerButton>
<span />
<span />
<span />
</HamburgerButton>
</MobileNavContainer>
);
}
the nth-child(2) selector seems to style the HamburgerButton component itself for some reason, so I can only imagine it's a syntax issue, although googling has done nothing to help me out with it.
https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
nth-child styles the element based on it's position within the group (this has confused me a million times over the years). HamburgerButton being the 2nd element within MobleNavContainer, it got styled. You want to add that class to the spans.
const HamburgerButton = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
min-height: 60%;
min-width: 50px;
border-radius: 8px;
& span:nth-child(1){
width: 32px;
min-height: 3px;
background-color: red;
}
& span:nth-child(2){
width: 32px;
min-height: 3px;
background-color: red;
}
& span:nth-child(3){
width: 32px;
min-height: 3px;
background-color: red;
}
`
Putting a space between the & and the : tells the code to look out for child components. with the way you've written it above it is telling the code to look for the nth HamburgerButton. you can also write the code I have above without the span if you want to reference any nth child element
& :nth-child(2){
color: red;
}
Example:
margin-right: 1rem;
:nth-child(*what ever number*) {
margin-right: 0;
}
to target every other child you can also replace what ever number with odd or even

Resources