如何将绝对定位的div水平居中于其相对定位的父级?

时间:2016-04-28 21:37:40

标签: javascript html css

我有一个具有动态大小的语音泡泡类,并且绝对定位。我希望它始终以水平居中于其相对定位的父元素,无论语音泡沫的大小是多少。我希望它看起来像这样(字母'O'是父相对定位的元素):

enter image description here

目前,如果我将left属性设置为0:

,它看起来像这样

enter image description here

如果我可以保证气泡的大小是固定的,那么这是一个容易解决的问题,但绝对不是。我无法通过在类width的元素上设置leftmargin-leftbubble来解决此问题。它需要比那更强大。

如果有的话,我更喜欢css解决方案。但是,如果唯一的解决方案是javascript,我也会考虑。

这就是代码的样子。请注意,智能气泡包装器上的边距并不是真正需要的,它们只是存在,因此您可以在代码示例中看到气泡:

.bubble-wrapper {
  position: relative;
  margin-top: 100px;
  margin-left: 100px;
}

.bubble {
  display: block;
  position: absolute;
  padding: 10px;
  background: #FFFFFF;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: solid 1px #bababf;
  box-shadow: 0px 0px 5px #6bcded;
  left: 0;
  color: #333333;
}

.bubble-bottom {
  bottom: 30px;
}

.bubble-middle-after {
  left: calc(50% - 8px);
}

.bubble-middle-before {
  left: calc(50% - 10px);
}

.bubble-bottom-before {
  bottom: -8px;
}

.bubble-bottom-after {
  bottom: -12px;
  border-width: 12px 12px 0;
  border-style: solid;
  border-color: #FFFFFF transparent;
}

.bubble-after {
  content: '';
  position: absolute;
  display: block;
}

.bubble-before {
  content: '';
  position: absolute;
  border-style: solid;
  border-color: #bababf;
  border-width: 13px 13px 0;
  background-color: white;
  display: block;
  box-shadow: 0px 0px 5px #6bcded;
  width: 0px;
  height: 10px;
  z-index: -1;
  transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}
<div class="bubble-wrapper">
  O
  <div class="bubble bubble-middle bubble-bottom" arrow-horizontal="middle" arrow-vertical="bottom">
    <div class="bubble-before bubble-middle-before bubble-bottom-before"></div>
    <span class="ng-scope">How do I center this bubble</span>
    <div class="bubble-after bubble-middle-after bubble-bottom-after"></div>
  </div>
</div>

2 个答案:

答案 0 :(得分:1)

您可以使用

  1. 选择足够长的x
  2. left设置为某个负值-x
  3. right设为calc(100% - x)
  4. 假设x足够大,绝对定位的元素将位于左侧中心。
  5. 但其宽度为2*x。使用width: fit-contentwidth: max-content来解决此问题。
  6. 但现在它过度约束了。将margin-leftmargin-right设置为auto以保持居中。
  7. 例如,选择x = 100%

    left: -100%;
    right: 0;
    width: fit-content; /* may need vendor prefixes */
    margin: 0 auto;
    

    .bubble-wrapper {
      position: relative;
      margin-top: 100px;
      margin-left: 100px;
    }
    .bubble {
      display: block;
      position: absolute;
      padding: 10px;
      background: #FFFFFF;
      -webkit-border-radius: 10px;
      -moz-border-radius: 10px;
      border-radius: 10px;
      border: solid 1px #bababf;
      box-shadow: 0px 0px 5px #6bcded;
      color: #333333;
    
      left: -100%;
      right: 0;
      width: -webkit-fit-content;
      width: -moz-fit-content;
      width: fit-content; /* may need vendor prefixes */
      margin: 0 auto;
    }
    .bubble-bottom {
      bottom: 30px;
    }
    .bubble-middle-after {
      left: calc(50% - 8px);
    }
    .bubble-middle-before {
      left: calc(50% - 10px);
    }
    .bubble-bottom-before {
      bottom: -8px;
    }
    .bubble-bottom-after {
      bottom: -12px;
      border-width: 12px 12px 0;
      border-style: solid;
      border-color: #FFFFFF transparent;
    }
    .bubble-after {
      content: '';
      position: absolute;
      display: block;
    }
    .bubble-before {
      content: '';
      position: absolute;
      border-style: solid;
      border-color: #bababf;
      border-width: 13px 13px 0;
      background-color: white;
      display: block;
      box-shadow: 0px 0px 5px #6bcded;
      width: 0px;
      height: 10px;
      z-index: -1;
      transform: rotate(45deg);
      -moz-transform: rotate(45deg);
      -ms-transform: rotate(45deg);
      -o-transform: rotate(45deg);
      -webkit-transform: rotate(45deg);
    }
    <div class="bubble-wrapper">
      O
      <div class="bubble bubble-middle bubble-bottom" arrow-horizontal="middle" arrow-vertical="bottom">
        <div class="bubble-before bubble-middle-before bubble-bottom-before"></div>
        <span class="ng-scope">How do I center this bubble</span>
        <div class="bubble-after bubble-middle-after bubble-bottom-after"></div>
      </div>
    </div>

    对于不支持width: fit-content的浏览器,您可以添加内联块内部包装器,该内部包装器可以text-align: center为中心。

    .bubble-wrapper {
      position: relative;
      margin-top: 100px;
      margin-left: 100px;
    }
    .bubble {
      display: block;
      position: absolute;
      left: -100%;
      right: 0;
      text-align: center;
      margin: 0 auto;
    }
    .bubble-inner-wrapper {
      position: relative;
      display: inline-block;
      vertical-align: middle;
      padding: 10px;
      background: #FFFFFF;
      -webkit-border-radius: 10px;
      -moz-border-radius: 10px;
      border-radius: 10px;
      border: solid 1px #bababf;
      box-shadow: 0px 0px 5px #6bcded;
      color: #333333;
    }
    .bubble-bottom {
      bottom: 30px;
    }
    .bubble-middle-after {
      left: calc(50% - 8px);
    }
    .bubble-middle-before {
      left: calc(50% - 10px);
    }
    .bubble-bottom-before {
      bottom: -8px;
    }
    .bubble-bottom-after {
      bottom: -12px;
      border-width: 12px 12px 0;
      border-style: solid;
      border-color: #FFFFFF transparent;
    }
    .bubble-after {
      content: '';
      position: absolute;
      display: block;
    }
    .bubble-before {
      content: '';
      position: absolute;
      border-style: solid;
      border-color: #bababf;
      border-width: 13px 13px 0;
      background-color: white;
      display: block;
      box-shadow: 0px 0px 5px #6bcded;
      width: 0px;
      height: 10px;
      z-index: -1;
      transform: rotate(45deg);
      -moz-transform: rotate(45deg);
      -ms-transform: rotate(45deg);
      -o-transform: rotate(45deg);
      -webkit-transform: rotate(45deg);
    }
    <div class="bubble-wrapper">
      O
      <div class="bubble bubble-middle bubble-bottom" arrow-horizontal="middle" arrow-vertical="bottom">
        <div class="bubble-inner-wrapper">
          <div class="bubble-before bubble-middle-before bubble-bottom-before"></div>
          <span class="ng-scope">How do I center this bubble</span>
          <div class="bubble-after bubble-middle-after bubble-bottom-after"></div>
        </div>
      </div>
    </div>

答案 1 :(得分:-1)

注意: Values of 0 shouldn't have units specified.

你也可以绝对重新定位你的泡泡。

.bubble-bottom-after:before { 
  content: 'O';
  position: absolute;
  left: -6px;
}

&#13;
&#13;
.smart-bubble-wrapper {
  position: relative;
  margin-top: 100px;
  margin-left: 100px;
}

.bubble-bottom-after:before { 
  content: 'O';
  position: absolute;
  left: -6px;
}

.bubble {
  display: block;
  position: absolute;
  padding: 10px;
  background: #FFF;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: solid 1px #bababf;
  box-shadow: 0 0 5px #6bcded;
  left: -105px;
  color: #333;
}

.bubble-bottom {
  bottom: 30px;
}

.bubble-middle-after {
  left: calc(50% - 8px);
}

.bubble-middle-before {
  left: calc(50% - 10px);
}

.bubble-bottom-before {
  bottom: -8px;
}

.bubble-bottom-after {
  bottom: -12px;
  border-width: 12px 12px 0;
  border-style: solid;
  border-color: #FFF transparent;
}

.bubble-after {
  content: '';
  position: absolute;
  display: block;
}

.bubble-before {
  content: '';
  position: absolute;
  border-style: solid;
  border-color: #bababf;
  border-width: 13px 13px 0;
  background-color: white;
  display: block;
  box-shadow: 0 0 5px #6bcded;
  width: 0;
  height: 10px;
  z-index: -1;
  transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}
&#13;
<link href="https://necolas.github.io/normalize.css/4.1.1/normalize.css" rel="stylesheet"/>
<div class="smart-bubble-wrapper">
  <div class="bubble bubble-middle bubble-bottom" arrow-horizontal="middle" arrow-vertical="bottom">
    <div class="bubble-before bubble-middle-before bubble-bottom-before"></div>
    <span class="ng-scope">How do I center this bubble</span>
    <div class="bubble-after bubble-middle-after bubble-bottom-after"></div>
  </div>
</div>
&#13;
&#13;
&#13;