Search code examples
htmlcsssassalignment

CSS max-width text sizing issues


I have an accordion style header which I need to align an absolute positioned icon next too. I can easily do this currently by setting the icon to absolute and the H3 title to relative and aligning it negative to the right.

The issue I am having is that my text has a max-width on mobile to stop it hitting the button aligned to the right leaving room for the icon. When the text hits this icon it spans 2 lines but the max-wisth means that my icon is no longer aligned with the text. Does anyone know any workarounds for this to align it neatly to the text

Example

See the image below for how the multiline header spans 2 lines and the max width puts the icon at the very end

enter image description here

annotated image

enter image description here

Code

CSS

h3 {
    margin-bottom: 0;
    display: inline-block;
    padding: 0;
    font-weight: 800 !important;
    color: #211850 !important;
    font-size: 17px !important;
    line-height: 25px;
    font-size: 15px;
    max-width: calc(50% - 19px);
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.fa-question-circle-o {
    position: absolute;
    top: 50%;
    right: -25px;
    transform: translateY(-50%);
    margin-left: 0;
}

HTML

 <h3>
    {{ agreement.sectionName }}
    <i class="fa fa-question-circle-o" (click)="openModal(agreement.sectionName, agreement.infoContent)"></i>
</h3>

Solution

  • One way of handling this is to use width: min-content which will set the width to the minimum required to display all the content.

    (Note: in the snippet, I had to add quite a bit of HTML and CSS to make it look like your screenshots; it would have been better if you'd have posted a Minimal, Complete, and Verifiable example).

    section {
      width: 290px;
      height: 61px;
      position: relative;
      background: #eaeaea;
      border-radius: .5em;
      margin: .5em;
    }
    
    h3 {
      margin: 0;
      display: inline-block;
      padding: 0;
      font-weight: 800 !important;
      color: #211850 !important;
      font-size: 17px !important;
      line-height: 25px;
      font-size: 15px;
      max-width: calc(50% - 19px);
      position: absolute;
      left:0; top: 50%;
      transform: translateY(-50%);
      /* debug */
      outline: 2px solid red;
      /* solution */
      width: min-intrinsic;         /* old Safari */
      width: -moz-min-content;      /* Firefox */
      width: -webkit-min-content;   /* old Chrome */
      width: min-content;           /* modern browsers */
    }
    
    .fa-question-circle-o {
      position: absolute;
      top: 50%;
      right: -25px;
      transform: translateY(-50%);
      margin-left: 2px;
    }
    
    /* emulate FA */
    .fa-question-circle-o::after {
      font-style: normal;
      content: '?';
      border: 2px solid;
      border-radius: 100%;
      display: inline-block;
      width: 1em;
      line-height: 1em;
      text-align: center;
      color:#969696;
    }
    <section>
      <h3>
        Test
        <i class="fa fa-question-circle-o" (click)="openModal(agreement.sectionName, agreement.infoContent)"></i>
      </h3>
    </section>
    <section>
      <h3>
        Testing
        <i class="fa fa-question-circle-o" (click)="openModal(agreement.sectionName, agreement.infoContent)"></i>
      </h3>
    </section>
    <section>
      <h3>
        Testing multiline
        <i class="fa fa-question-circle-o" (click)="openModal(agreement.sectionName, agreement.infoContent)"></i>
      </h3>
    </section>

    Warnings:

    • This doesn't work in IE and Edge. If you need to support those, this solution is out
    • The width of the h3 will become the minimum required to display all the content; which may not be what you want. Change the content of the first one from "Test" to "X Y Z" to see what I mean.