[CSS Challenge]: Creating a resizable textbox that can stretch vertically and horizontally without warping corner elements

Viewed 94

I am creating a resizable textbox that can stretch vertically and horizontally without warping graphical corner elements. To do so, I am using three vertical sections (top, center, bottom) and three horizontal sections (left, middle, right) within the top and bottom vertical sections. This way, the 'top-middle' and 'bottom-middle' sections can stretch horizontally and the center section can stretch vertically & horizontally, while the corner sections (top-left, top-right, bottom-left..) stay the same width and height to avoid warping.

The problem is: positioning elements so that they line up with one another. Specifically, I seem to be getting some cut-off on the right sides of my corner elements.

Here's a screenshot of the issue: https://postimg.cc/Xp4dRDrQ

Here is the HTML:

<div className='textbox-container'>
  <div className='top-block'>
    <div className='left-block' />
    <div className='middle-block'>
      <p>
        Top Block
      </p>
    </div>
    <div className='right-block' />
  </div>
  
  <div className='center-block'>
    <p>
      Center Block
    </p>
  </div>
  
  <div className='bottom-block'>
    <div className='left-block' />
    <div className='middle-block'>
      <p>
        Bottom Block
      </p>
    </div>
    <div className='right-block' />
  </div>
</div>

And here is the CSS I am using:

.textbox-container {
    display: flex;
    flex-flow: column;
    align-items: center;
    width: 75%;
    margin: 0 auto;
  }

  .top-block {
    display: inline-flex;
    flex-direction: row;
    float: left;
    width: 100%;
    height: 80px;
    margin:0 auto;
    margin-top: 10vh;
  }

  .top-block .left-block {
    background-image: url('/src/images/Textbox-Top-Left.png');
    background-repeat: no-repeat;
    background-size: cover;
    width: 150px;
    height: 80px;
    margin:0 auto;
  }

  .top-block .middle-block {
    width: 100%;
    height: 80px;
    line-height: 80px;
    text-align: right;
    vertical-align: middle;
    background-image: url('/src/images/Textbox-Top-Middle.png');
    color: #fff;
    margin:0 auto;
  }
  
  .top-block .right-block {
    float:right;
    background-image: url('/src/images/Textbox-Top-Right.png');
    background-repeat: no-repeat;
    background-size: cover;
    width: 150px;
    height: 80px;
    margin:0 auto;
  }

  .center-block {
    display: flex;
    flex-flow: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 800px;
    background-image: url('/src/images/Textbox-Center.png');
    background-repeat: repeat-y;
    background-size: contain;
    margin: 0;
  }

  .bottom-block {
    display: inline-flex;
    flex-direction: row;
    float: left;
    width: 100%;
    height: 80px;
    margin-bottom: 20vh;
  }

  /* Close but no cigar with magic numbers in bot sections: */
  .bottom-block .left-block {
    width: 220px;
    height: 80px;
    background-image: url('/src/images/Textbox-Bottom-Left.png')
  }

  .bottom-block .middle-block {
    width: 100%;
    line-height: 80px;
    text-align: right;
    padding-right: 5vw;
    vertical-align: middle;
    height: 80px;
    background-image: url('/src/images/Textbox-Bottom-Middle.png');
    color: #fff;
    margin: none;
  }

  .bottom-block .right-block {
    float:right;
    width: 220px;
    height: 80px;
    background-image: url('/src/images/Textbox-Bottom-Right.png')
  }

Fiddle (currently not working): https://jsfiddle.net/edmundw/6xku4qwa/6/

Fiddle collaborate invite: https://jsfiddle.net/edmundw/6xku4qwa/4/#&togetherjs=4VMz2rGNAo

Any solutions would be greatly appreciated as I am stumped.

Many thanks for reading this far,

Betty.

1 Answers

Hm, I got something working by using actual img elements (which have an inherent width and height) for the individual sections, along with flexbox (specifically flex-basis, flex-grow and flex-shrink).

The only problem I can see is that the center element's background's borders are blurry. Not sure how to fix that, but other than that, it works. No border cutoff.

* {
    padding: 0px;
    margin: 0px;

    box-sizing: border-box;
}

.textbox-container {
    width: min-content;
    height: auto;

    overflow: hidden;

    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: center;
}

.textbox-vertical-block {
    width: 100%;
    max-width: 100%;
    height: 80px;

    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: center;
}

.textbox-vertical-block>* {
    width: auto;
    height: 100%;

    object-fit: fill;
}

.textbox-vertical-block>*:nth-child(2) {
    flex-basis: auto;
    flex-grow: 1;
    flex-shrink: 0;
}

.textbox-center-block {
    height: auto;

    align-items: stretch;

    background-image: url(https://i.postimg.cc/d3p7Nt38/Textbox-Center.png);
    background-size: 100% 100%;
    background-repeat: repeat;
}

.textbox-center-block.textbox-vertical-block>* {
    height: initial;
}

.textbox-center-block>.textbox-block {
    width: 6px;
}

.textbox-center-block>textarea {
    width: auto;
    height: auto;

    flex-basis: auto;
    flex-grow: 1;
    flex-shrink: 1;

    margin: 16px;
    padding: 16px;
}
<div class="textbox-container">
    <div class="textbox-vertical-block">
        <img class="textbox-block" src="https://i.postimg.cc/jDn9G5wH/Textbox-Top-Left.png" />
        <img class="textbox-block" src="https://i.postimg.cc/qtfY0Ty9/Textbox-Top-Middle.png" />
        <img class="textbox-block" src="https://i.postimg.cc/8FhYz0bs/Textbox-Top-Right.png" />
    </div>
    <div class="textbox-vertical-block textbox-center-block">
        <img class="textbox-block" src="https://i.postimg.cc/xcrz8TS0/Textbox-Center-Right.png" />
        <textarea></textarea>
        <img class="textbox-block" src="https://i.postimg.cc/xcrz8TS0/Textbox-Center-Right.png" />
    </div>
    <div class="textbox-vertical-block">
        <img class="textbox-block" src="https://i.postimg.cc/kD70BqzC/Textbox-Bottom-Left.png" />
        <img class="textbox-block" src="https://i.postimg.cc/CdJW89pq/Textbox-Bottom-Middle.png" />
        <img class="textbox-block" src="https://i.postimg.cc/dL1gjnJS/Textbox-Bottom-Right.png" />
    </div>
</div>

EDIT #1: Removed the blur by using the same method used in the top and bottom sections (extra border and center images (the center image is 1x1 though, so could be easily replaced by background-color)). More flexbox foolery too

Related