Which magic CSS causes the difference of text-vertical-align between <button> and
?

后端 未结 3 1423
闹比i
闹比i 2021-01-04 02:06

I found that the text inside of

3条回答
  • 2021-01-04 02:23

    If you look at Chrome source code you can kind of see how it works, at least for Chrome. It seems there's an anonymous flex box created with a specific style applied. It's not that straightforward — at least not for me — but still, you can deduce what style is applied to this anonymous element. You can see here: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/LayoutButton.cpp?sq=package:chromium

    The interesting part:

    void LayoutButton::updateAnonymousChildStyle(const LayoutObject& child,
                                                 ComputedStyle& childStyle) const {
      ASSERT(!m_inner || &child == m_inner);
    
      childStyle.setFlexGrow(1.0f);
      // min-width: 0; is needed for correct shrinking.
      childStyle.setMinWidth(Length(0, Fixed));
      // Use margin:auto instead of align-items:center to get safe centering, i.e.
      // when the content overflows, treat it the same as align-items: flex-start.
      childStyle.setMarginTop(Length());
      childStyle.setMarginBottom(Length());
      childStyle.setFlexDirection(style()->flexDirection());
      childStyle.setJustifyContent(style()->justifyContent());
      childStyle.setFlexWrap(style()->flexWrap());
      // TODO (lajava): An anonymous box must not be used to resolve children's auto
      // values.
      childStyle.setAlignItems(style()->alignItems());
      childStyle.setAlignContent(style()->alignContent());
    }
    

    This gives something like this :

    div span {
      display: flex;
      text-align: center; 
      min-width: 0px;
      flex-grow: 1;
      justify-content: center;
      cursor: default;
      margin: 0 auto;
      height: 100%;
      align-items: center;
      align-content: center;
    }
    

    Then you just need to wrap the div content in that span and apply the style. All these rules are probably not all necessary or accurate but the result seems ok:

    div,
    button {
      width: 4em;
      height: 4em;
      background-color: red;
      padding: 0;
      border: 0;
      margin: 1em;
      font-size: 1em;
      font-family: Arial;
      float: left;
    }
    div span {
      display: flex;
      text-align: center;
      min-width: 0px;
      flex-grow: 1;
      justify-content: center;
      cursor: default;
      margin: 0 auto;
      width: 100%;
      height: 100%;
      align-items: center;
      align-content: center;
    }
    <div><span>text text</span>
    </div>
    <button>text text</button>
    
    <div><span>text text text text</span>
    </div>
    <button>text text text text</button>
    
    <div><span>text text text text text text</span>
    </div>
    <button>text text text text text text</button>

    0 讨论(0)
  • 2021-01-04 02:28

    Since you are using inline-block, you need to use vertical-align as the default is baseline:

    Magic CSS:

    vertical-align: middle;
    

    The above will fix it:

    div,
    button {
      width: 4em;
      height: 4em;
      background-color: red;
      padding: 0;
      border: 0;
      margin: 1em;
      font-size: 1em;
      font-family: Arial;
      vertical-align: middle;
    }
    
    div {
      text-align: center;
      display: inline-block;
      cursor: default;
      box-sizing: border-box;
    }
    <div>text</div>
    <button>text</button>

    And for the text inside the div to be centred, you need to use line-height to the height of the div.

    Magic CSS:

    line-height: 4em;
    

    div,
    button {
      width: 4em;
      height: 4em;
      background-color: red;
      padding: 0;
      border: 0;
      margin: 1em;
      font-size: 1em;
      font-family: Arial;
      vertical-align: middle;
      line-height: 4em;
    }
    
    div {
      text-align: center;
      display: inline-block;
      cursor: default;
      box-sizing: border-box;
    }
    <div>text</div>
    <button>text</button>

    0 讨论(0)
  • 2021-01-04 02:36

    I think you may consider one of the following solutions

    Solution #1

    Add these to the div style

    display: table-cell;

    vertical-align: middle;

    If you still need to use inline-block display, you can use nested div, the parent div will be displayed as (inline-block), the child div will be displayed as (table-cell) and that's where you middle the text.

    Solution #2

    You can set the div padding and line height dynamically using jQuery .. and this will be done on the run time, and will be adjusted based on the size of the content inside the div. you can check this question jquery set line-height equal to parent container height

    0 讨论(0)
提交回复
热议问题