Nested flexbox align-items center specific content

时间:2018-03-09 19:01:11

标签: html css css3 flexbox css-grid

I'm trying to build the simple form below.

enter image description here

I'm using flexbox and having trouble aligning the textarea properly. align-items: center aligns the whole div. I've tried taking the textarea div out and am having trouble aligning the textarea relative to the above flexbox container. How can I acheive the above textbox position while having the x, photo, name and aligned centered.

fiddle

.container {
  display: flex;
}
.content {
  flex-grow: 1;
}
textarea {
  width: 100%;
}
img {
  border-radius: 30px;
  margin: 0 10px;
}
<div class="container">
  <div>
    x
  </div>
  <div>
   <img src="http://via.placeholder.com/50x50">
  </div>
  <div class="content">
    <div>Brad</div>
    <div>Boston</div>
    <textarea></textarea>
  </div>
</div>

2 个答案:

答案 0 :(得分:5)

CSS Grid

For a simple and efficient solution use Grid Layout. No need to set any fixed widths.

.container {
  display: grid;
  align-items: center;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: auto auto;  /* optional; implicit rows are auto by default */
  grid-template-areas:  "close  avatar   name    "
                        "   .     .     textbox ";
}

.container > *:nth-child(1) { grid-area: close; }
.container > *:nth-child(2) { grid-area: avatar; }
.container > *:nth-child(3) { grid-area: name; }
.container > *:nth-child(4) { grid-area: textbox; }

img {
  vertical-align: top; /* remove descender space applied to inline-level elements */
  border-radius: 30px;
  margin: 0 10px;
}
.container > * {
  border: 1px dashed red;
  box-sizing: border-box;
}
<div class="container">
  <div>x</div>
  <div>
    <img src="http://via.placeholder.com/50x50">
  </div>
  <div class="content">
    <div>Brad</div>
    <div>Boston</div>
  </div>
  <textarea></textarea>
</div>

Flexbox

If you want to stick with flexbox, here's one method, but it requires more details to render properly.

  • Allow the container to wrap items (flex-wrap: wrap)
  • Force the textarea onto its own row (e.g. flex-basis: 100%)
  • Define a width for the "x" and the avatar
  • Subtract the width of the x & avatar from the textarea width
  • Left-align the textarea with an auto margin

.container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.container > div:nth-child(-n + 2) {
  flex: 0 0 50px;
  text-align: center;
}

.container > div:nth-child(3) {
  flex: 1;
}

img {
  display:block;
  border-radius: 30px;
  margin: 0 10px;
}

textarea {
  margin-left: auto;
  flex: 0 0 calc(100% - 120px);
}

.container > * {
  border: 1px dashed red;
  box-sizing: border-box;
}
<div class="container">
  <div>x</div>
  <div>
    <img src="http://via.placeholder.com/50x50">
  </div>
  <div class="content">
    <div>Brad</div>
    <div>Boston</div>
  </div>
  <textarea></textarea>
</div>


答案 1 :(得分:3)

You can try something like this:

.container {
  display: flex;
  align-items:center;
  flex-wrap:wrap; /* we force a wrap so textarea is in the next line*/
}
.content {
  flex-grow: 1;
}
textarea {
  flex-basis: 100%;
  margin-left:80px; /* use margin to adjust, change this value depending the icon and image width */
}
img {
  border-radius: 30px;
  margin: 0 10px;
}
<div class="container">
  <div>
    x
  </div>
  <!-- better remove the div around the image, it's useless and avoid having a white space issue -->
  <img src="http://via.placeholder.com/50x50">
  <div class="content">
    <div>Brad</div>
    <div>Boston</div>
  </div>
  <!-- we make it out of content -->
  <textarea></textarea>
</div>