Reputation: 373
I want to recreate the same design as the second image below using CSS grid. I got a problem with the alignment, of course because of the two spans the inputs are not aligned like they should be. I am almost there with CSS grid but i can't figure it out. Is there a way to do it with grid or is there another solution for this?
<div className="grade-card">
<div className="grade-card-header">
<span className="title">{this.props.title}</span>
</div>
<div className="grade-card-body">
<div className="grade-input">
<span>I</span>
<input type="text"/>
<span>1x</span>
</div>
<div className="grade-input">
<span>I</span>
<input type="text"/>
<span>Min</span>
</div>
<div className="grade-input">
<span>I</span>
<input type="text"/>
<span>1x</span>
</div>
<div className="grade-input">
<span>I</span>
<input type="text"/>
</div>
<div className="grade-input">
<span>I</span>
<input type="text"/>
</div>
<div className="grade-input">
<input type="text"/>
</div>
</div>
</div>
.grade-card{
width: 349px;
height: 384px;
background-color: white;
border-radius: 28px;
.grade-card-header{
display: flex;
align-items: center;
justify-content: center;
height: 20%;
border-radius: 28px 28px 0 0;
background-color: #1089FF;
.title{
color: white;
font-size: 1.5em;
}
}
.grade-card-body{
height: 80%;
cursor: pointer;
display: grid;
grid-template-columns: repeat(2, 174.5px);
grid-template-rows: repeat(3, 102.4px);
justify-items: center;//horizontally
align-items: center;//vertically
input{
outline: none;
width: 74px;
height: 51px;
border: 1px solid #707070;
border-radius: 6px;
font-size: 1.3em;
text-align: center;
}
.grade-input:last-child{
input{
width: 117px;
height: 69px;
}
}
}
}
Upvotes: 0
Views: 678
Reputation: 1147
This is a little of a variation on @Brice's answer, because in his version:
This version solves it, but the idea to use absolute positioning to escape the flow is the same.
/*********** begin changes **********/
.grade-input {
position: relative;
}
.label {
position: absolute;
top: 50%;
}
.label-left {
transform: translate(calc(-100% - 6px), -50%);
}
.label-right {
transform: translate(6px, -50%);
}
/*********** end changes **********/
.grade-card {
width: 349px;
height: 384px;
background-color: white;
border-radius: 28px;
}
.grade-card .grade-card-header {
display: flex;
align-items: center;
justify-content: center;
height: 20%;
border-radius: 28px 28px 0 0;
background-color: #1089ff;
}
.grade-card .grade-card-header .title {
color: white;
font-size: 1.5em;
}
.grade-card .grade-card-body {
height: 80%;
cursor: pointer;
display: grid;
grid-template-columns: repeat(2, 174.5px);
grid-template-rows: repeat(3, 102.4px);
justify-items: center;
align-items: center;
}
.grade-card .grade-card-body input {
outline: none;
width: 74px;
height: 51px;
border: 1px solid #707070;
border-radius: 6px;
font-size: 1.3em;
text-align: center;
}
.grade-card .grade-card-body .grade-input:last-child input {
width: 117px;
height: 69px;
}
<div class="grade-card">
<div class="grade-card-header">
<span class="title">{this.props.title}</span>
</div>
<div class="grade-card-body">
<div class="grade-input">
<span class="label label-left">I</span>
<input type="text"/>
<span class="label label-right">1x</span>
</div>
<div class="grade-input">
<span class="label label-left">I</span>
<input type="text"/>
<span class="label label-right">Min</span>
</div>
<div class="grade-input">
<span class="label label-left">I</span>
<input type="text"/>
<span class="label label-right">1x</span>
</div>
<div class="grade-input">
<span class="label label-left">I</span>
<input type="text"/>
</div>
<div class="grade-input">
<span class="label label-left">I</span>
<input type="text"/>
</div>
<div class="grade-input">
<input type="text"/>
</div>
</div>
</div>
Upvotes: 1
Reputation: 96
Because the spans are different values, your .grade-input
divs are becoming different widths and that is throwing off your alignment.
EDITED to get inputs aligned exactly centered:
If you make the spans position: absolute;
, then you would be able to just align the inputs.
Try below HTML:
<div className="grade-card">
<div className="grade-card-header">
<span className="title">{this.props.title}</span>
</div>
<div className="grade-card-body">
<div className="grade-input">
<span className="left-absolute">I</span>
<input type="text"/>
<span className="right-absolute oneX">1x</span>
</div>
<div className="grade-input">
<span className="left-absolute">I</span>
<input type="text"/>
<span className="right-absolute min">Min</span>
</div>
<div className="grade-input">
<span className="left-absolute">I</span>
<input type="text"/>
<span className="right-absolute oneX">1x</span>
</div>
<div className="grade-input">
<span className="left-absolute">I</span>
<input type="text"/>
</div>
<div className="grade-input">
<span className="left-absolute">I</span>
<input type="text"/>
</div>
<div className="grade-input">
<input type="text"/>
</div>
</div>
</div>
Add below to your css file:
.grade-input {
position: relative;
}
.left-absolute {
position: absolute;
left: -7px;
top: 20px;
}
.right-absolute.oneX {
position: absolute;
right: -15px;
top: 20px;
}
.right-absolute.min {
position: absolute;
right: -27px;
top: 20px;
}
Upvotes: 0