Search code examples
htmlcssflexboxmargintext-alignment

How can I align varying length text flexbox elements to fixed-size iframe flexbox elements?


After introducing flexbox columns along with iframe flexbox rows, the iframe rows shift left to right variably depending on the length of the text, and the text does not align above the iframes. So, to align the text to begin leftmost where the iframes start, and directly above them, I used relative positioning. This hack only works when each p tag text is of the same length. If they vary, or if I increase their character counts all uniformly, the alignment with the iframes breaks.

Here is the css:

.serv div {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  row-gap: 83px;
  margin-right: 44px;
  margin-left: 44px;
}
.serv p {
  font-size: 10px;
  color: #000000;
  position: relative;
  flex-direction: column;
  left: 71.75px;
  top: -19px;
  margin-left: -72px;
}

Is there a way to prevent the text from translating the iframe rows, and is there a way to snap the text to begin in line with the iframes, even as p tag text lengths vary?

Example: https://jsfiddle.net/gnoj1h0r/8/


Solution

  • Not sure why you have the extra div element, I don't see any purpose for that.

    If I understand the layout you're going for, this should give you a cleaner start...

    You have rows (.serv). Inside each row you have containers (.container). The containers have the img/iframe + p stacked normally, don't need any special CSS to line up the left edge.

    Then your 83px gap that before was separating your containers, is moved to the container as a margin to separate the containers.

    Seems to me the biggest problem with your original code is having a plain div inside a plain div (no classes). And using .serv div as a CSS selector. That CSS is going to apply to your top div under .serv, and all of the divs under that div. That's why the row-gap was applying to the nested divs. Having a CSS selector so unspecific and HTML without classes is inviting trouble IMO. Best to use class names and good specific selectors to avoid unintended consequences.

    Note: I added an extra .serv row to show wrapping.

    .serv {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: center;
      margin-right: 44px;
      margin-left: 44px;
      border: 2px solid red;
    }
    
    .serv .container {
      margin-right: 83px; /* I moved this here to separate your container divs inside the row */
      border: 2px solid blue;
    }
    
    .serv p {
      font-size: 10px;
      color: #000000;
    }
    <div class="serv">
        <div class="container">
          <p>test test</p>
          <iframe style="background:grey" width="100" height="100" frameborder="0"> </iframe>
        </div>
        
        <div class="container">
          <p>test</p>
          <iframe style="background:grey" width="100" height="100" frameborder="0"> </iframe>
        </div>
      </div>
      
      <div class="serv">
        <div class="container">
          <p>test test</p>
          <iframe style="background:grey" width="100" height="100" frameborder="0"> </iframe>
        </div>
        
        <div class="container">
          <p>test</p>
          <iframe style="background:grey" width="100" height="100" frameborder="0"> </iframe>
        </div>
      </div>