Question: Center one element along with multiple siblings

Question

Center one element along with multiple siblings

Answers 3
Added at 2016-12-31 16:12
Tags
Question

I have a div with some number of spans in it, that may or may not be of equal width. I know I can use text-align: center to make all the content within a div be centered. However, I want to pick a particular span, and designate that as the true center, rather than the center being the midpoint of the sequence of spans.

One idea I had to simulate this effect was: I'd have my desired middle element with two containers to its left and right; the left one would be right-justified, and vice-versa. These containers would hold the other content in the div. If I could get these two containers to fill up the remaining space in equal amounts, this would have the effect of centering the middle element while keeping the left and right content aligned with the center. Basically, this would require the two containers' width to be set to exactly half the remaining space in the div. (I don't want to change the size of the middle div.) Is this possible to do with just CSS?

Example: with 4 spans, how to I designate span 2 as the true center?

div {
  width: 500px;
  padding: 4px;
  border: 1px dotted black;
}
span {
  display: inline-block;
  width: 100px;
  text-align: center;
  margin: 4px;
  box-sizing: border-box;
  border: 1px dotted black;
}
#b {
  /* ??? */
}
<div>
  <span id="a">1</span>
  <span id="b">2</span>
  <span id="c">3</span>
  <span id="d">4</span>
</div>

Answers to

Center one element along with multiple siblings

nr: #1 dodano: 2016-12-31 16:12

This can be done using flexbox. You can use display:flex; on the div, and use flex-grow:1; on the 2nd span. That way you can cover the whole div with that span.

Since the 1st and 3rd spans are already equal in width, you'll have the 2nd span in dead center. And then use flex-basis on the 2nd to get it's desired width.

div.container{
  width: 500px;
  padding: 4px;
  border: 1px dotted black;
}
div.row{
  display:flex;
  align-items:center;
  justify-content:center;
}
span {
  display: inline-block;
  width: 70px;
  text-align: center;
  margin: 4px;
  box-sizing: border-box;
  border: 1px dotted black;
  transform:translate(50%,0);
}
#b {
}
<html>

<head></head>

<body>
  <div class='container'>
    <div class="row">
      <span id="a">1</span>
      <span id="b">2</span>
      <span id="c">3</span>
      <span id="d">4</span>
    </div>
  </div>
</body>

</html>

nr: #2 dodano: 2016-12-31 19:12

I suggest to do it with a 3 column layout, and use CSS table structure. Make the 1st and 3rd columns to take 50% of total width, and middle column will have only 0, but it will recalculate the width to fit the content and remains center since it's in a table.

Also put white-space: nowrap; there in case there are multiple words inside, but remove it as needed if there is only one word or fixed width.

.container {
  display: table;
  border-collapse: collapse;
  width: 100%;
}
.item {
  display: table-cell;
  vertical-align: top;
  padding: 4px;
  border: 1px solid grey;
}
.item-a {
  width: 50%;
  text-align: right;
}
.item-b {
  text-align: center;
  white-space: nowrap; /* remove as needed */
}
.item-c {
  width: 50%;
}
.item span {
  display: inline-block;
  border: 1px solid red;
}
.item-b span {
  padding: 0 50px; /* for demo only */
}
<div class="container">
  <span class="item item-a">
    <span>1</span>
  </span>
  <span class="item item-b">
    <span>2</span>
  </span>
  <span class="item item-c">
    <span>3</span>
    <span>4</span>
  </span>
</div>

jsFiddle

nr: #3 dodano: 2016-12-31 20:12

You can use flexbox. Based on this answer,

.outer-wrapper {
  display: flex;
  padding: 4px;
  border: 1px dotted black;
}
.item {
  margin: 4px;
  text-align: center;
  border: 1px dotted black;
}
.left.inner-wrapper, .right.inner-wrapper {
  flex: 1;
  display: flex;
  align-items: flex-start;
  min-width: -webkit-min-content; /* Workaround to Chrome bug */
}
.left.inner-wrapper {
  justify-content: flex-end;
}
.animate {
  animation: anim 5s infinite alternate;
}
@keyframes anim {
  from { min-width: 0 }
  to { min-width: 50vw; }
}
<div class="outer-wrapper">
  <div class="left inner-wrapper">
    <div class="item animate">1. Left</div>
  </div>
  <div class="center inner-wrapper">
    <div class="item">2. Center</div>
  </div>
  <div class="right inner-wrapper">
    <div class="item">3. Right</div>
    <div class="item">4. Right</div>
  </div>
</div>
<!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">1. Left</div></div><div class="center inner-wrapper"><div class="item animate">2. Center</div></div><div class="right inner-wrapper"><div class="item">3. Right</div><div class="item">4. Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">1. Left</div></div><div class="center inner-wrapper"><div class="item">2. Center</div></div><div class="right inner-wrapper"><div class="item animate">3. Right</div><div class="item">4. Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">1. Left</div></div><div class="center inner-wrapper"><div class="item">2. Center</div></div><div class="right inner-wrapper"><div class="item">3. Right</div><div class="item animate">4. Right</div></div></div>

This will attempt to center the desired element, but it will be pushed in case one side doesn't fit, to prevent overlapping.

Source Show
◀ Wstecz