Multi-line label for radio button - javascript

I would like "This is label" text to stack right underneath the "Prefix Text", while radio button to be aligned right next "Prefix Text". Is it possible to get this done by updating class for div element that contains "This is label" only? I would like to keep label-container class untouched if possible as I may add icon in front of "Prefix Text" so I will need display: inline-flex to wrap them up. https://codepen.io/Judoboy/pen/OJQqPEW?editors=1100
.label-container {
display: inline-flex;
justify-content: flex-start;
align-items: center;
}
.label-text {
display: flex;
justify-items: center;
align-items: center;
height: 100%;
}
.prefix {
font-weight: bold;
}
.text-spacing {
padding-inline-start: 8px;
padding-inline-end: 4px;
}
<label class="label-container">
<input type="radio" />
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing">This is label</div>
</label>

You can do this:
Wrap both Prefix Text and This is label with additional div.
Change align-items in .label-container class to start (you can keep display: inline-flex).
.label-container {
display: inline-flex;
justify-content: flex-start;
align-items: start;
}
.label-text {
display: flex;
justify-items: center;
align-items: center;
height: 100%;
}
.prefix {
font-weight: bold;
}
.text-spacing {
padding-inline-start: 8px;
padding-inline-end: 4px;
}
<label class="label-container">
<input type="radio" />
<div>
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing">This is label</div>
</div>
</label>

just use some transform.
.AlignmentFix {
transform: translate(-100%, 17px);
}
<label class="label-container">
<input type="radio" />
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing AlignmentFix">This is label</div>
</label>

// finding the only <button> element in the document, and binding
// an anonymous Arrow function as the event-handler for the 'click'
// event on that <button>:
document.querySelector('button').addEventListener('click', (e) => {
// we retrieve the first element in the document that matches
// the selector supplied to document.querySelector():
let original = document.querySelector('label.label-container'),
// we then clone that node, and its descendant elements
// with the Boolean true argument passed to Node.cloneNode():
clone = original.cloneNode(true);
// e.currentTarget is the element to which the anonymous function
// was bound; from that element we navigate to the first ancestor
// element that matches the selector and then append the 'clone'
// to that <main> element:
e.currentTarget.closest('main').append(clone);
});
/* overriding browser default layout calculations,
and zeroing all margin and padding for cross-
browser consistency: */
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* element added for layout purposes, to avoid changing the <body>
element's styles in case of conflict with your real-world
preferences: */
main {
border: 1px solid #000;
border-radius: 1em;
display: flex;
flex-flow: row wrap;
gap: 0.5em;
justify-content: space-between;
margin-block: 1em;
margin-inline: auto;
padding: 0.5em;
width: clamp(10rem, 60vw, 1000px);
}
/* styling the <button> to occupy the whole width, or a full
'row': */
button:first-child {
flex-basis: 100%;
flex-grow: 1;
padding-block: 0.5em;
}
.label-container {
/* while 'inline grid' (note the space) is a valid property-
value, regardless of Chrome's claim to the contrary,
I've changed the property-value to 'inline-grid' for
compatibility with Chrome, Edge, etc: */
display: inline-grid;
/* here we create a grid-layout of two columns, and two
rows with three 'cells'. The first cell is placed in
the first column, and spans both rows. The other
cells take only one 'cell' each. */
grid-template-areas: "radio prefix" "radio text";
}
.label-text {
display: flex;
justify-items: center;
align-items: center;
height: 100%;
}
.prefix {
font-weight: bold;
}
input {
align-self: center;
}
.text-spacing {
grid-column: 2;
padding-inline-start: 8px;
padding-inline-end: 4px;
}
<!-- this element is purely for the wrapping, to supply padding and layout; obviously
adjust to your preferences: -->
<main>
<!-- added a <button> to handle the addition of new <label> elements to demonstrate the layout -->
<button>Add another <label> element</button>
<label class="label-container">
<input type="radio">
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing">This is label</div>
</label>
<label class="label-container">
<input type="radio">
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing">This is label</div>
</label>
<label class="label-container">
<input type="radio">
<div class="label-text text-spacing prefix">Prefix Text</div>
<div class="label-text text-spacing">This is label</div>
</label>
</main>
JS Fiddle demo.

Related

How to extend a div backwards?

Does anyone know how to extend a div 2 to the back, lowering the div 1 to the down, when clicking, in a simple way? It looks easy but with css it is not possible and with javascript it is difficult.
I want when clicking on the 2 extends back and the 1 goes down:
But instead this happens:
div 2 goes down.
Html and Css:
.frame {
width: 50%;
height: 400px;
font: bold 70px roboto;
color: black;
background-color: yellow;
float: left;
}
input:checked + .frame {
width: 100%;
}
input{
display: none;
}
<body class="gallery">
<input type="checkbox" id="a" />
<label for="a" class="frame a">1</label>
<input type="checkbox" id="b" />
<label for="b" class="frame b" style="background-color: green">2</label>
<input type="checkbox" id="c" />
<label for="c" class="frame a" style="background-color: green">3</label>
<input type="checkbox" id="d" />
<label for="d" class="frame b">4</label>
</body>
I tried with this javascript:
Demo
To Make the clicked div moves above all:
You can easily do that:
1-Make the gallery parent flex
2-Give order: 2; for all children
3-Change the order to 1 when checked
Apply:
body{
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.frame {
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
text-align: center;
order: 2;
}
input:checked + .frame {
width: 100%;
order: 1;
}
input{
display: none;
}
<body class="gallery">
<input type="checkbox" id="a"/>
<label for="a" class="frame" style="outline: 2px solid">1</label>
<input type="checkbox" id="b"/>
<label for="b" class="frame" style="outline: 2px solid">2</label>
<input type="checkbox" id="c"/>
<label for="c" class="frame" style="outline: 2px solid">3</label>
<input type="checkbox" id="d"/>
<label for="d" class="frame" style="outline: 2px solid">4</label>
<input type="checkbox" id="e"/>
<label for="e" class="frame" style="outline: 2px solid">5</label>
<input type="checkbox" id="f"/>
<label for="f" class="frame" style="outline: 2px solid">6</label>
</body>
And now, when you click anyone, it will go to the top and fill the parent width.
And when you click another one while the first is still active, it will be move to the top too and fill the parent width without affecting the older one.
If you want to stop having many frames selected at the top, just turn your inputs to be radio instead of checkbox and connect them all with the same name attribute.
To make the clicked div moves above its brother only:
Here you must dived every two frames in a separate row div and do the same job for the rest.
Apply:
body {
margin: 0;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.frame {
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
text-align: center;
order: 2;
}
input:checked + .frame {
width: 100%;
order: 1;
}
input {
display: none;
}
<body class="gallery">
<div class="row">
<input type="checkbox" id="a" />
<label for="a" class="frame" style="outline: 2px solid">1</label>
<input type="checkbox" id="b" />
<label for="b" class="frame" style="outline: 2px solid">2</label>
</div>
<div class="row">
<input type="checkbox" id="c" />
<label for="c" class="frame" style="outline: 2px solid">3</label>
<input type="checkbox" id="d" />
<label for="d" class="frame" style="outline: 2px solid">4</label>
</div>
<div class="row">
<input type="checkbox" id="e" />
<label for="e" class="frame" style="outline: 2px solid">5</label>
<input type="checkbox" id="f" />
<label for="f" class="frame" style="outline: 2px solid">6</label>
</div>
</body>
Now if you clicked a div, it will go above its brother only, there is a small difference that the other elements will not merge with its brother.
And absolutely there is many many many other ways using css or javascript, but I think the first one does what you want.
Nice question. Yep, it does not have pure-css solution, unfortunately...
Fully agree with previous comment regarding to "swapping" strategy via "order" css property. It's definitely less code and more performant then "physically moving" html elements in DOM
Also, "display: grid" is always better then flex for multi-dimensional layouts (2-column in our case)
Supposing that initial requirement expects that any "even cell" should behave as "2", I see full solution like this:
const el_cells = document.querySelectorAll('.wrapper .cell');
el_cells.forEach((el_clicked, index) => {
const el_prev = index > 0 ? el_cells[index - 1] : null;
el_clicked.addEventListener('click', () => {
// checking if element was already expanded
const expanding = !el_clicked.classList.contains('active')
// restoring initial cells state
el_cells.forEach((el, i) => {
el.classList.remove('active');
el.style.order = i + 1;
});
if (expanding) {
// resizing selected cell
el_clicked.classList.add('active');
// swapping 'even' cell with previous one (f.e. 2 with 1, 4 with 3, etc...)
if (index % 2 === 1) {
el_clicked.style.order--;
el_prev.style.order++;
}
}
})
})
/* some not very important global styles */
* {
margin: 0;
padding: 0;
font-size: 40px;
font-weight: bold;
}
/* our yellow-green grid */
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrapper .cell {
height: 100px;
background: yellow;
}
.wrapper .cell.green {
background: green;
}
.wrapper .cell.active {
grid-column: span 2;
}
<div class="wrapper">
<div class="cell">1</div>
<div class="cell green">2</div>
<div class="cell green">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell green">6</div>
<div class="cell green">7</div>
<div class="cell">8</div>
</div>
Improved this example a bit to make expanded cells to collapse on click :)
"Uladzimir Interesting, when you click on 2 it extends, then you click on 4 and everyone else resets. Can you tell me how to keep the 2 extended after clicking another one?"
Well, this small clarification adds additional "layer of complexity" to the initial question :)
The reason is that when initially you click "2" - you know that all "even elements" should push "odd ones" below them. On the other hand, when "2" gets expanded and you click "5" - how system should behave if not getting "2" collapsed ?
Seems that "5" has to push "4" below like "2" did that with "1".
So now logics of re-ordering elements has to become "generic" not like it was previously (re-ordering even-index elements when clicked)
And now user clicks, for example, "3", how to process this situation then ? Where do we have to push "1" in this case ? Under "5" probably ? I do not know... But, you see, lots of "edge cases" start appearing here...
What's bad here is that if you implement that - the solution would be definitely bulky, dirty and not very readable and understandable, unfortunately... So, I think, the best way here - to suggest your customers some easier-to-implement option (for example as I suggested initially when collapsing previously expanded elements)
Just a possible and not "too complicated" variant is to list selected elements always "on top":
const el_cells = document.querySelectorAll('.wrapper .cell');
let el_expanded = [];
el_cells.forEach((el_clicked) => {
el_clicked.addEventListener('click', () => {
const expanding = !el_clicked.classList.contains('active');
// resizing/collapsing current cell
if (expanding) {
el_clicked.classList.add('active');
} else {
el_clicked.classList.remove('active');
}
// refreshing expanded element collection
if (expanding) {
el_expanded = [el_clicked, ...el_expanded];
} else {
el_expanded = el_expanded.filter(_ => _ !== el_clicked);
}
// re-indexing not-expanded elements
el_cells.forEach((el, idx) => {
if (el_expanded.indexOf(el) !== -1) return;
el.style.order = 1000 + idx + 1 // 1000 added here to list them after "expanded" ones
})
// re-indexing expanded elements
el_expanded.forEach((el, idx) => {
el.style.order = idx + 1;
})
});
});
/* some not very important global styles */
* {
margin: 0;
padding: 0;
font-size: 40px;
font-weight: bold;
}
/* our yellow-green grid */
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrapper .cell {
height: 100px;
background: yellow;
}
.wrapper .cell.green {
background: green;
}
.wrapper .cell.active {
grid-column: span 2;
}
<div class="wrapper">
<div class="cell">1</div>
<div class="cell green">2</div>
<div class="cell green">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell green">6</div>
<div class="cell green">7</div>
<div class="cell">8</div>
</div>
Again, this is not "ideal" option, you see. With lots of elements in list it would also require some "scroll-to-top" logics :( Anyway, it is understandable, predictable and requires "not too much" code to create and maintain

How to align div class "gs" and div class "fl" in same line and in center

I am trying to design Google search page and facing some problems.
I have completed almost every thing but got stuck in aligning "Google Search" button and "I am feeling Lucky button" in line and in center below search bar.
Below is my HTML and CSS for entire layout.
body,a{
font-family: Arial, Helvetica, sans-serif;
text-decoration: none;
padding: 5px;
margin: 5px;
text-align: center;
}
.i{
margin-left: auto;
margin-right: auto;
margin-top: 135px;
}
nav{
text-align: right;
padding-top: 5px;
}
.sb input{
border-radius: 25px ;
border: 0.5px solid ;
height: 40px;
width: 480px;
}
.foo{
font-size: medium;
padding-left: 40px;
padding-right: 40px;
}
<nav>
<div>
Google Image Search
Advance Search
</div>
</nav>
<img src="image.png" class="i">
<form action="https://google.com/search" class="f">
<div class="sb">
<input type="text" name="q" class="foo">
</div>
<div class="gs">
<input type="submit" value="Google Search">
</div>
</form>
<div class="fl">
<a href="https://www.google.com/doodles">
<button>I am feeling lucky</button>
</a>
</div>
Here is my output: http://jsfiddle.net/zqwmogvd/#&togetherjs=Rd6Qeg60cd
Here is how I would do it. I would wrap the two buttons in a parent div with a classname buttons-wrap or any class name of my choosing:
<form action="https://google.com/search" class="f">
<div class="sb">
<input type="text" name="q" class="foo">
</div>
<div class="buttons-wrap">
<div class="gs">
<input type="submit" value="Google Search">
</div>
<div class="fl">
<a href="https://www.google.com/doodles">
<button>I am feeling lucky</button>
</a>
</div>
</div>
</form>
I would then reference the .buttons-wrap class in CSS and use flexbox to center it:
.buttons-wrap {
display: flex;
justify-content: center;
margin-top: 3px;
}
If you don't know flexbox, you can also use the following:
.buttons-wrap>div {
display: inline-block;
margin-top: 3px
}
> selects the children elements.
.button-wrap {
display: flex;
justify-content:center;
margin-top:10px
}
flex is the value of css display. By using display:flex in parent elements, child elements automatically align like columns or rows with auto width and auto height.
The CSS justify-content property defines how the browser distributes space between and around content items along the main-axis of a flex container.

Add event listener to items inside flex container

I have a flex container that contains several items that have the flex-grow property set to 1 and a certain max-width.
I want to add an event listener to the group of items, but I do not want the event to fire if the event location is in the empty space of the flex container. For example, for a click event, I want the event to fire only if the blue space of the image below is clicked.
If I add the event listener to the parent container, the event fires even if I click the purple. If I add the event listener to the child items, the event does not fire when if I click on the margins of the items. In addition, for events like onmouseenter or onmouseleave, the event fires 3 times if I move my mouse over all the items, whereas my desire is for it to only fire once.
Here is a snippet of the current scenario:
$(".flex-container").on("mouseenter", () => {
$("#hidden").show();
})
$(".flex-container").on("mouseleave", () => {
$("#hidden").hide();
})
$(".flex-item").on("mouseenter", () => {
$("#hidden2").show();
})
$(".flex-item").on("mouseleave", () => {
$("#hidden2").hide();
})
.flex-container {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
margin: 5px;
padding: 5px;
}
.item-container {
display: flex;
align-items: center;
width: 100%;
justify-content: center;
}
.flex-item {
padding: 5px;
margin: 10px;
outline: 1px solid black;
flex: 1 1 auto;
height: 24px;
max-width: 24px;
display: flex;
align-items: center;
justify-content: center;
}
#hidden, #hidden2 {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex-container">
<div class="flex-item">
1
</div>
<div class="flex-item">
2
</div>
<div class="flex-item">
3
</div>
</div>
<div id="hidden">
Flex Container Hovered
</div>
<div id="hidden2">
Flex Item Hovered
</div>
Adding an extra flex container as a wrapper achieves close to the intended effect, but the intention of the flex-grow property of the items is not preserved, as seen below.
The items do not grow to the max-width of the items to fill up the outer box. Here is a snippet of the above scenario:
$(".flex-container").on("mouseenter", () => {
$("#hidden").show();
})
$(".flex-container").on("mouseleave", () => {
$("#hidden").hide();
})
$(".flex-item").on("mouseenter", () => {
$("#hidden2").show();
})
$(".flex-item").on("mouseleave", () => {
$("#hidden2").hide();
})
$(".extra-wrapper").on("mouseenter", () => {
$("#hidden3").show();
})
$(".extra-wrapper").on("mouseleave", () => {
$("#hidden3").hide();
})
.flex-container {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
margin: 5px;
padding: 5px;
}
.extra-wrapper {
display: flex;
}
.item-container {
display: flex;
align-items: center;
width: 100%;
justify-content: center;
}
.flex-item {
padding: 5px;
margin: 10px;
outline: 1px solid black;
flex: 1 1 auto;
height: 24px;
max-width: 24px;
display: flex;
align-items: center;
justify-content: center;
}
#hidden, #hidden2, #hidden3 {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex-container">
<div class="extra-wrapper">
<div class="flex-item">
1
</div>
<div class="flex-item">
2
</div>
<div class="flex-item">
3
</div>
</div>
</div>
<div id="hidden">
Flex Container Hovered
</div>
<div id="hidden2">
Flex Item Hovered
</div>
<div id="hidden3">
Extra Wrapper Hovered
</div>
How do I add an event listener to the items in a flex container when the items have a flex-grow and a max-width property?
Try this: https://jsfiddle.net/sean7777/zngdr51k/11/
How 2 make it work
It works because since margin does not count in mouseleave and mouseenter events, we use a wrapper element around the flex-item, wrap. The wrapper then gets assigned padding, and you attach the event listener to the wrapper.
This way you can simulate margin as padding and make it work with the event listner.
Note that you will have to assign width and height to the box. In the example, if you remove the width/height, it won't look right.
Building upon the suggested answer from #ourmandave, I came up with the following solution.
In this solution, I added a pseudo element to each flex-item so that I could include the elements' margins in the events' "hot spots" as they were called. I then used additional logic to prevent the event handlers from repeated triggers by using the event's related target. By checking where the cursor used to be upon mouseleave or mouseenter events, one can prevent the event handlers from being fired again when the mouse moves from one flex item to another flex item. This solution still preserves the desired effects of flex-grow and max-width.
$(".flex-container").on("mouseenter", () => {
$("#hidden").show();
})
$(".flex-container").on("mouseleave", () => {
$("#hidden").hide();
})
$(".flex-item").on("mouseenter", (e) => {
if (e.relatedTarget.className === "flex-item") return;
console.log('mouseenter fired');
$("#hidden2").show();
})
$(".flex-item").on("mouseleave", (e) => {
if (e.relatedTarget.className === "flex-item") return;
console.log('mouseleave fired');
$("#hidden2").hide();
})
.flex-container {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
margin: 5px;
padding: 5px;
}
.item-container {
display: flex;
align-items: center;
width: 100%;
justify-content: center;
}
.flex-item {
padding: 5px;
margin: 10px;
outline: 1px solid black;
flex: 1 1 auto;
height: 24px;
max-width: 24px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.flex-item::before {
content: '';
position: absolute;
inset: -10px -10px -10px -10px;
}
#hidden, #hidden2 {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex-container">
<div class="flex-item">
1
</div>
<div class="flex-item">
2
</div>
<div class="flex-item">
3
</div>
</div>
<div id="hidden">
Flex Container Hovered
</div>
<div id="hidden2">
Flex Item Hovered
</div>

How to get the text next to my checkbox inline, and next to checkbox?

I am working on a web page in which I need the text associated with each text to be next to the checkbox. Currently, this is what it looks like:
I do not want any of the checkboxes or labels associated with them to be centered. I want them to be aligned to the left. Here are my JavaScript & global style code:
JS:
import React from 'react'
import { Link } from 'react-router-dom';
import { Form } from '../../global styles/index';
import { useForm } from 'react-hook-form';
function ArtistForm(){
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => console.log(data);
console.log(errors);
return(
<div>
<Form onSubmit={handleSubmit(onSubmit)}>
<div className="form-container">
<div className="row">
<div className="column">
<label>First Name:</label>
<input type="text" placeholder="First Name" name="FirstName" ref={register({required: true, max: 30, min: 2})} />
</div>
<div className="column">
<label>Last Name:</label>
<input type="text" placeholder="Last Name" name="LastName" ref={register({max: 30, min: 2})} />
</div>
</div>
<div>
<label>Medium:</label>
<input type="checkbox" id= "designillustration" name="medium" /><span>Design & Illustration</span>
<input type="checkbox" id="digitalart" name="medium" /><span>Digital Art</span>
<input type="checkbox" id="drawing" name="medium" /><span>Drawing</span>
<input type="checkbox" id="paintingmixedmedia" name="medium" /><span>Painting & Mixed Media</span>
<input type="checkbox" id="photography" name="medium" /><span>Photography</span>
</div>
<div>
<label>Artist Bio: </label>
<textarea placeholder="Bio" name="Bio" ref={register({required: true, maxLength: 500})} />
</div>
</Form>
</div>
)
}
export default ArtistForm
Global Style for Form Component:
// form styling
export const Form = styled.form`
max-width: 1000px;
margin: 0 auto;
label {
float: left;
text-align: left;
display: inline-block;
padding-left: 15px;
text-indent: -15px;
}
input {
box-sizing: border-box;
width: 100%;
border-radius: 4px;
padding: 10px 15px;
margin-bottom: 10px;
font-size: 14px;
margin-top: 10px;
display: block;
}
textarea {
box-sizing: border-box;
width: 100%;
border-radius: 4px;
padding: 10px 15px;
margin-bottom: 10px;
font-size: 14px;
}
.form-container {
display: flex;
flex-direction: column;
width: 90%;
padding: 20px;
#media(max-width: 500px){
padding: 20px 50px 50px;
}
}
div {
display: inline-block, flex;
flex-direction: row;
justify-content: flex-start;
padding: .2rem;
}
p {
margin: 0;
}
.instructions{
text-align: center;
margin-bottom: 40px;
}
.column {
float: left;
width: 50%;
padding: 10px;
}
.row:after {
content: "";
display: table;
clear: both;
}
`
Is there something with the input tag that is interfering with how the checkboxes show up with the labels for them? I have tried over and over again to use display: inline-block but for some reason I cannot get the text to be inline with the checkbox. I have also tried to align the text to the left for the label but did not have any luck.
From your code, the solution can be done in 3 steps:
removing the following styles from the input selector
width: 100%;
display: block;
Both of these styles were giving your input element the width: 100% which pushes the text below.
Then from there, what I would do is wrap each of the input and span pairs in divs. This will section off the two inline elements into its own container while allocating the full width to the elements e.g.
<div>
<input type="checkbox" id= "designillustration" name="medium" />
<span>Design & Illustration</span>
</div>
Add the following css to restore width: 100% on the text inputs
input[type="text"] {
width: 100%;
}
Here is a codepen that demonstrates the solution on the first checkbox input row: https://codepen.io/ariellav/pen/poyvPKR
Other note:
Replacing
label {
float: left;
text-align: left;
display: inline-block;
padding-left: 15px;
text-indent: -15px;
}
with
label {
display: block;
}
should reap the same result
you've set your
input{
width: 100%;
}
that takes the whole width of the container and doesn't allow the text to display inline
You have to have label tags next that are to/for the input button. Also, you must get rid of your input{width: 100%;}
<input type="checkbox" id="designillustration" name="medium"/>
<label for="designillustration">Design & Illustration</label>

How can I create a list where I can add and remove inputs via buttons?

I've an idea. For this I need a list like this draw:
So the main idea is to have a plus and a minus button. When a users presses the plus button, another input get's added. When pressing the minus button beside each input, the related input should be removed.
So I've startet with this here but I'm not very with it and the functionality is not given yet. How can I deal with this a smart way? Is there a problem with the id's? I mean I could copy a row or insert it (with JS) but how can I get the values later of all inputs in one map (with JS) for example? A lot of questions..
.out-task {
display: flex;
margin-bottom: 8px;
}
.delete-task-button {
margin-left: 6px;
background: red;
}
.button {
width: 30px;
height: 30px;
display: block;
border-radius: 50%;
color: white;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.add-task-button {
background: green;
}
<div class="wrapper">
<label>Tasks</label>
<div id="tasks-wrapper">
<div class="out-task">
<input type="text" id="task" name="task" value="">
<span class="delete-task-button button">-</span>
</div>
</div>
<span class="add-task-button button">+</span>
</div>
Thanks for helping me out!!!
As I have criticized everyone, I let you do the same on my code:
const ListTasks = document.querySelector('#wrapper > div')
, PosInsertTask = document.querySelector('#wrapper > div > span.add-task-button')
, taskWrapper = document.querySelector('#template > div')
;
ListTasks.onclick=e=>
{
if (e.target.classList.contains('add-task-button'))
{
let newTask = taskWrapper.cloneNode(true)
ListTasks.insertBefore(newTask, PosInsertTask)
}
else if (e.target.classList.contains('delete-task-button'))
{
ListTasks.removeChild(e.target.closest('.out-task'))
}
}
.out-task {
display : flex;
margin-bottom: 8px;
}
.delete-task-button {
margin-left: 6px;
background : red;
}
.button {
width : 30px;
height : 30px;
display : block;
border-radius : 50%;
color : white;
display : flex;
justify-content: center;
align-items : center;
cursor : pointer;
font-weight : bold;
}
#wrapper { display: inline-block; border: 1px solid grey; padding:.8em;}
#wrapper h4 { text-align: center; }
.add-task-button {
background: green;
margin: auto;
}
#template { display: none;}
<div id="wrapper">
<h4>Tasks</h4>
<div>
<div class="out-task">
<input type="text" value="">
<span class="delete-task-button button">-</span>
</div>
<span class="add-task-button button">+</span>
</div>
</div>
<div id="template">
<div class="out-task">
<input type="text" value="">
<span class="delete-task-button button">-</span>
</div>
</div>

Categories

Resources