List in CSS Grid Not Aligning as Expected [duplicate] - html

This question already has answers here:
How do I remove the first empty column in a CSS grid?
(3 answers)
Closed 4 years ago.
Problem / Misunderstanding:
I've created an input type="radio" for radio choices. The radio choices should align to the left at the beginning of column 3, but instead they are in the middle, between column 3 and 4.
Expected behavior:
Radio input options should be at the beginning of column 3, under aligning with the text input bar of the Name label.
Minimal, complete and verifiable code below.
MCV.html code:
<link rel="stylesheet" href="MCP.css">
<div class="grid-container">
<form id="survey-form">
<label for="name" id="name-label">Name:</label>
<input type="text" id="name">
<div class="radio-title">
<p>Gender:</p>
</div>
<div class="radio-options">
<ul>
<li>
<input type="radio" id="choice-1">
<label for="choice-1">Option A</label>
</li>
<li>
<input type="radio" id="choice-1">
<label for="choice-1">Option B</label>
</li>
</ul>
</div>
</form>
</div>
MCV.css code:
.grid-container {
display: grid;
grid-template-areas:
". . . ."
". c c ."
". . . .";
grid-template-columns: 0.7fr 1.5fr 1.5fr 0.7fr;
grid-template-rows: 0.7fr 1.5fr 0.7fr;
}
#survey-form {
display: grid;
grid-area: c;
grid-template-columns: repeat(4, 1fr);
grid-gap: 5px;
}
label {
grid-column: 2 / 3;
text-align: right;
}
input {
text-align: left;
}
ul {
list-style: none;
}
.radio-title {
grid-column: 2;
text-align: right;
}
.radio-options {
grid-column: 3 / 4;
text-align: left;
}
Here's an image with line numbers and form grid:
All feedback is appreciated, thank you!
NOTE: This issue was already answered in How do I remove the first empty column in a css grid?. Take a look at second answer.

I believe this is more of a List issue. Most browsers attach some sort of padding / margin to an element so most people clear these out before starting on a new page.
Going to your codepen use:
//css
.gender ul {
padding: 0;
}
and you'll see the buttons move over to your desired location.

Related

How to style child component html elements to parent component grid?

I have a component with a grid defined, I want to style a child component input elements so that they stay in a specific grid row and column; I tried doing this;
parent component html;
<div class="patient-details-grid">
<app-child-component></app-child-component>
</div>
.patient-details-grid {
gap: 15px 40px;
grid-template-columns: repeat(4, 1fr);
display: grid;
}
app-child-component {
.form {
display: block;
.firstName {
grid-area: 2 / 1 / 2 / 2;
}
.lastName,
.year,
.city,
.zipCode,
.phone,
.email {
grid-column: 1 / 3;
}
}
The form elements do not get placed into the correct grid tracks as I expected. How do I style these child elements into the parent div grid? the child component has multiple input elements like this;
<input type="text" class="firstName">
<input type="text" class="lastName">
<input type="text" class="year">
<input type="text" class="city">
<input type="text" class="zipCode">
<input type="text" class="phone">
<input type="text" class="email">

Conditionally place item within grid layout

I have a few scenarios in my grid. I have 4 possible grid elements, but depending on a user selection from the previous screen, I might only display three of those.
I'm running into an issue where in a particular circumstance, I want to display only 3 elements (2 per row), with the third element on the bottom row placed to the far right, essentially leaving an empty space where the first element of the second row normally would be.
const MyGrid = styled(OtherGrid)`
#media (max-width: ${BP.SMALL - 1}px) {
div:nth-child(2) {
grid-row-start: 3;
}
div:nth-child(3) {
grid-row-start: 2;
}
}
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 1fr;
`;
My grid is styled from another grid, but all in all, acts like a basic grid.
<MyGrid>
<FormGroup
type={"number"}
name={"initial_moisture"}
label={"Initial Moisture (%)"}
step={0.1}
required
/>
<FormGroup
type={"number"}
name={"initial_temp"}
label={`Initial Temperature (${isMetric ? "C" : "F"})`}
step={1}
required
/>
{operatingMode != "auto_cool" && (
<>
<FormGroup
type={"number"}
name={"final_moisture"}
label={"Target Moisture (%)"}
step={0.1}
required
/>
</>
)}
{operatingMode != "auto_hydrate" && (
<>
<FormGroup
class={"auto-cool"}
type={"number"}
name={"final_temp"}
label={`Target Temperature (${isMetric ? "C" : "F"})`}
step={1}
required
/>
</>
)}
</MyGrid>
In the last possible state here (operatingMode != "auto-hydrate"), I want to place that element on the second row, but in the second column as well, and leave an empty space on the 2nd row, first column. Is there something within my parent container GoalsFieldGrid that I can define that will help me do this?
grid-column: -1; is what I'm looking for, but I'm not sure how to apply it in that specific scenario.
If I understand correctly you only require this when there are three elements only.
That being the case you can use :nth-child(3):last-child to select the element.
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 1fr;
margin-bottom: 1em;
gap: .25em;
}
.item {
display: flex;
justify-content: center;
align-items: center;
padding: 1em;
border: 1px solid grey;
}
.item:nth-child(3):last-child {
grid-column: 2;
}
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>

How to create tabbed navigation for variable number of columns using ONLY CSS

I am trying to create a general solution to a problem I encounter fairly often.
I am attempting to use the checkbox hack in tandem with a CSS grid in order to create a tabbed navigation menu that doesn't need to be modified when the HTML changes. If you run the code snippet, you'll see that you can add or remove any of the input/label/section trios and the CSS can just handle it.
What I am failing to accomplish is getting the second row to span all columns effectively filling the available space. I have come to understand that I am unable to get a row to span all columns unless I define an explicit grid. Unfortunately, defining a set number of columns defeats the whole purpose of what I am trying to do.
Working under the constraint that the HTML will always be input/label/section blocks in that order, is there any way to get that second row to span all columns without defining a set number of columns? I tried to get this to work using flexbox, but I couldn't get the columns right.
I am trying to get this with just CSS please, no javascript.
#Wrapper {
display: grid;
grid-auto-columns: 1fr;
grid-template-rows: 2em calc(100% - 2em);
height: 100%;
width: 100%;
}
#Wrapper section,
input[name=buttons] {
display: none
}
/*This doesn't work*/
#Wrapper section {
grid-column-start: 1;
grid-column-end: -1;
}
#Wrapper input[name=buttons]+label {
border-style: solid;
border-width: 1px;
cursor: pointer;
grid-row-start: 1;
grid-row-end: 2;
}
#Wrapper>input[name=buttons]:checked+label {
background-color: red;
}
#Wrapper>input[name=buttons]:checked+label+section {
display: block;
width: 100%;
}
<div id='Wrapper'>
<input type='radio' id='TabButton1' name='buttons' checked></input>
<label for='TabButton1'>SECTION 1</label>
<section>
This is some content 1
</section>
<input type='radio' id='TabButton2' name='buttons'></input>
<label for='TabButton2'>SECTION 2</label>
<section>
This is some content 2
</section>
<input type='radio' id='TabButton3' name='buttons'></input>
<label for='TabButton3'>SECTION 3</label>
<section>
This is some content 3
</section>
<input type='radio' id='TabButton4' name='buttons'></input>
<label for='TabButton4'>SECTION 4</label>
<section>
This is some content 4
</section>
<input type='radio' id='TabButton5' name='buttons'></input>
<label for='TabButton5'>SECTION 5</label>
<section>
This is some content 5
</section>
</div>

Form alignment collapses into single row

I have the parent element set to newTableForm with labelColumn and mainFormColumn as children - but with the current CSS everything collapses into one row:
.newTableForm {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 30px 30px 30px 40px;
grid-gap: 10px;
grid-template-areas: "... main" "labels main" "labels main" "... main";
border: 2px dashed deeppink;
}
.labelColumn {
grid-area: labels;
}
.mainFormColumn {
grid-area: main;
}
<form method='post' action="/admin-post.php" class="newTableForm">
<h4 class="mainFormColumn">
Add a new price compare table
</h4>
<label for="store" class="labelColumn">Store</label>
<input type="text" name="store" placeholder="" class="mainFormColumn"/>
<label for="product-page" class="labelColumn">Product Page Link</label>
<input type="text" name="product-page" placeholder="Copy address here" class="mainFormColumn" />
<button class="mainFormColumn">Save new price compare table</button>
</form>
Is there a way to undo the single column stacking behavior here? I would remove the template areas altogether if not for the blank sections with ... (above and below the label section)
Again you can drop grid-template-areas as multiple grid-areas overlap - and you can use pseudo elements for this:
place labelColumn into the first column using grid-column: 1 and mainFormColumn into the second column using grid-column: 2.
after element will be the first column in the last row using grid-row: -2 and grid-column: 1
before will be first column in the first row using grid-column: 1
See demo below:
.newTableForm {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 30px 30px 30px 40px;
grid-gap: 10px;
border: 2px dashed deeppink;
}
.labelColumn {
grid-column: 1;
}
.mainFormColumn {
grid-column: 2;
}
.newTableForm:after, .newTableForm:before {
content: '';
display: block;
grid-column: 1;
}
.newTableForm:after {
grid-row: -2;
}
<form method='post' action="/admin-post.php" class="newTableForm">
<h4 class="mainFormColumn">
Add a new price compare table
</h4>
<label for="store" class="labelColumn">Store</label>
<input type="text" name="store" placeholder="" class="mainFormColumn"/>
<label for="product-page" class="labelColumn">Product Page Link</label>
<input type="text" name="product-page" placeholder="Copy address here" class="mainFormColumn" />
<button class="mainFormColumn">Save new price compare table</button>
</form>
I just update your .newTableForm css with some updates. I hope it'll help you out. Thanks
.newTableForm {
display: flex;
flex-direction: column;
border: 2px dashed deeppink;
}

Divs inside a grid item?

I am using a Grid layout, and I am trying to place an image next to a text inside of the same griditem. The image is like an icon and supposed to be right next to the text (as it's placed in the code below). The text next to it is also supposed to have a different color and font than the rest of the text. I previously tried this with a span. However, when I use any of those tags inside the griditem it kinda breaks the grid. Instead of being a normal wall of text, it's suddenly all next to each other. I've been trying to figure this out for a couple hours now, can anyone help?
.container {
display: grid;
grid-template: repeat(4, auto) 300px 150px / repeat(6, 1fr);
grid-gap: 3px;
grid-template-areas: ". . h h . ." ". . img img . ." "a a a a a a" ". t t t t ." ". p1 p2 p3 p4 ." ". sm sm hp hp .";
}
.text {
display: flex;
grid-area: t;
font-size: 1vw;
font-family: Verdana;
border: 1px solid #3f3f3f;
border-radius: 25px;
padding: 2%;
}
<div class="container">
<div class="text">Hi!<br><br> Just a quick note to say thank you for making an account with SuperBath.co.uk!
<br><br> Having a SuperBath.co.uk account will give you the following perks:<br>
<br>
<img src="..scratches/Drop.jpg">Saved personal details<br> Personal data is instantly available as you log in with your email address and password. <br><br>
</div>
</div>
The main problem here is that because you use display: flex on text, the img becomes a flex row item and the text before and after the image, will become anonymous flex items, hence they line up side-by-side.
There is mainly two ways to solve that, where one solution is to wrap the whole text/image chunk in a span, and then, to enable a different color on the text next to the img, also wrap it with a span.
Stack snippet
.container {
display: grid;
grid-template: repeat(4, auto) 300px 150px / repeat(6, 1fr);
grid-gap: 3px;
grid-template-areas: ". . h h . ." ". . img img . ." "a a a a a a" ". t t t t ." ". p1 p2 p3 p4 ." ". sm sm hp hp .";
}
.text {
display: flex;
grid-area: t;
font-size: 1vw;
font-family: Verdana;
border: 1px solid #3f3f3f;
border-radius: 25px;
padding: 2%;
}
.text span span {
color: blue /* added */
}
<div class="container">
<div class="text"><span>Hi!
<br>
<br> Just a quick note to say thank you for making an account with SuperBath.co.uk!
<br>
<br> Having a SuperBath.co.uk account will give you the following perks:
<br>
<br>
<img src="http://placehold.it/15/00f"><span>Saved personal details</span>
<br> Personal data is instantly available as you log in with your email address and password.
<br>
<br></span>
</div>
</div>
Or as suggested in a comment, simply remove display: flex from the text, and only wrap the text that should have different color with a span.
Stack snippet
.container {
display: grid;
grid-template: repeat(4, auto) 300px 150px / repeat(6, 1fr);
grid-gap: 3px;
grid-template-areas: ". . h h . ." ". . img img . ." "a a a a a a" ". t t t t ." ". p1 p2 p3 p4 ." ". sm sm hp hp .";
}
.text {
grid-area: t;
font-size: 1vw;
font-family: Verdana;
border: 1px solid #3f3f3f;
border-radius: 25px;
padding: 2%;
}
.text span {
color: blue /* added */
}
<div class="container">
<div class="text">Hi!
<br>
<br> Just a quick note to say thank you for making an account with SuperBath.co.uk!
<br>
<br> Having a SuperBath.co.uk account will give you the following perks:
<br>
<br>
<img src="http://placehold.it/15/00f"><span>Saved personal details</span>
<br> Personal data is instantly available as you log in with your email address and password.
<br>
<br>
</div>
</div>