Align Container to top and bottom of Text

vertical-align: bottom not working
vertical-align text in div
align div to bottom of parent
vertical-align: middle not working
css position bottom of div
css vertical-align text
align-items to top of div
vertical-align div

I'm trying to align a colored rectangle to the left of two Text widgets. Specifically, I want the bottom of the colored rectangle to align with the baseline of the lower Text and the top of the rectangle to align with the cap height of the upper Text. Here is a mock of what I'm trying to achieve: My code so far:

final TextStyle helloTextStyle = const TextStyle(
  fontWeight: FontWeight.w600,
  fontSize: 28,
  letterSpacing: 0,
  wordSpacing: 0,
  fontFamily: "DejaVuSansCondensed",
  color: Color(0XFF232444),
  decoration: TextDecoration.none,
);
final TextStyle everyoneTextStyle = const TextStyle(
  fontWeight: FontWeight.w700,
  fontSize: 38,
  letterSpacing: 0,
  fontFamily: "DejaVuSansCondensed",
  color: Color(0XFF232444),
  decoration: TextDecoration.none,
);

return Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Container(
      decoration: BoxDecoration(
        border: Border(
          left: BorderSide(
              width: 16.0,
              color: Colors.red),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text("HELLO", style: helloTextStyle),
          Text("EVERYONE", style: everyoneTextStyle),
        ],
      ),
    ),
  ],
)

How would I align the bottom of the colored rectangle with the baseline of the lower Text and align the the top of the rectangle to the cap height of the upper Text?

Edit: One solution would be to determine the distance between the baseline and the bottom of the Text widget as well as the distance between the cap height and the top of the Text widget. Text widget doesn't appear to offer those values though.

wrap you Row in a Container with its height property defined :

 Container(
  height: MediaQuery.of(context).size.height/4 ,
  child: Row(
    children: <Widget>[
      Column(
       children: <Widget>[
          Container(
           width: 16.0,
           color: Colors.red,
          ),
        ]
      ),
      Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Text("HELLO", style: helloTextStyle),
          Text("EVERYONE", style: everyoneTextStyle),
        ]
      ),
    ]
  ),
 ),

vertical-align, text-top – Aligns the top of the element with the top of the parent element's font. text-bottom – Aligns the bottom of the element with the bottom of the parent element's font. sub – Aligns the baseline of the element with the subscript-baseline of its parent. Like where a <sub> would sit. HTML Text Align is required when you want a text presentation according to posing on any webpage. A Text Alignment can be Center, Right, Top, Bottom, Justify, or Vertical Horizontal. For HTML Text Alignment have to use a CSS style.

You Don't need to put Column as child of Container as you did. That way it won't Baseline with Text.

One way doing it:

double fontSize1 = 38.0;
double fontSize2 = 28.0;

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: IntrinsicHeight(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(top:(fontSize2 / 4.5),bottom: (fontSize1 / 4.2)),
                child: Container(
                  decoration: BoxDecoration(
                    border: Border(
                      left: BorderSide(
                          width: 16.0,
                          color: Colors.red),
                    ),
                  ),
                ),
              ),
              Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text("HELLO", style: helloTextStyle),
                  Text("EVERYONE", style: everyoneTextStyle),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

Output:

with:

  double fontSize1 = 68.0;
  double fontSize2 = 18.0;

output:

so Padding is calculated auto now.

How to Align the Content of a Div Element to the Bottom, Also, we can align the content to the top of a <div>, to the bottom on the left or on the Use the text-align property to align the inner content of the block element. You can align all the text in a text box with the top, middle, or bottom of the text box. Click the outer edge of the text box to select it. On the Shape Format tab, click Format Pane. Click the Shape Options tab if it isn't already selected.

There is no Flutter API for getting the exact bounds of the text. Flutter: finding the exact bounds of text covers this. That said, I have a solution based on the same discussion.

The approach is to paint a character (a capital 'I' in my case) to a canvas and then scan the image pixels looking for the edge of the character. I count the rows of pixels between the character and image edge and use that to set the padding on the colored block. My solution is a little more involved because I have two Text widgets within a Column and each Text is a different size.

Note: I wouldn't advise this solution unless you really care about a precise alignment with the edge of the character.

The layout code:

IntrinsicHeight(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
      FutureBuilder<TopBottomPadding>(
          future: _calcPadding(
              TextSpan(
                  text: "I", style: helloTextStyle),
              TextSpan(
                  text: "I", style: everyoneTextStyle),
              mediaQueryData.textScaleFactor),
          builder: (BuildContext context, tuple) {
            return Padding(
              padding: EdgeInsets.only(
                top: tuple.data.top,
                bottom: tuple.data.bottom,
              ),
              child: Container(
                decoration: BoxDecoration(
                  border: Border(
                    left: BorderSide(
                        width: 16.0, color: Colors.red),
                  ),
                ),
              ),
            );
          }),
      Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text("HELLO", style: helloTextStyle),
          Text("EVERYONE", style: everyoneTextStyle),
        ],
      ),
    ],
  ),
)

Generating the image involves an async call and so I've enlisted the FutureBuilder widget.

Future<TopBottomPadding> _calcPadding(final TextSpan topSpan,
    final TextSpan bottomSpan, final double textScaleFactor) async {
  final topPadding = await _calcTopPadding(topSpan, textScaleFactor);
  final bottomPadding = await _calcBottomPadding(bottomSpan, textScaleFactor);
  return TopBottomPadding(topPadding, bottomPadding);
}

Future<double> _calcTopPadding(TextSpan span, double textScaleFactor) async {
  final int bytesPerPixel = 4;
  final imageData =
      await _getImageByteData(span, ImageByteFormat.rawRgba, textScaleFactor);
  final Size imageSize = imageData.size;
  final ByteData byteData = imageData.byteData;
  final numRows =
      (byteData.lengthInBytes / (bytesPerPixel * imageSize.width)).round();
  int foundRow;
  /// Scan each pixel from top to bottom keeping track of the row
  for (int row = 0; row < numRows && foundRow == null; row++) {
    final int rowLength = bytesPerPixel * imageSize.width.round();
    final int startRowByteIndex = row * rowLength;
    /// Only looking at first byte of each pixel is good enough
    for (int byteArrayIndex = startRowByteIndex;
        byteArrayIndex < row * rowLength + rowLength;
        byteArrayIndex += bytesPerPixel) { 
      final int byteValue = byteData.getUint8(byteArrayIndex);
      /// The background is white so look for a non-white pixel.
      if (foundRow == null && byteValue != 0xff) {
        foundRow = row;
        break;
      }
    }
  }
  final double result = foundRow == null ? 0 : foundRow.toDouble();
  return result;
}

Future<double> _calcBottomPadding(
    final TextSpan span, final textScaleFactor) async {
  final int bytesPerPixel = 4;
  final imageData =
      await _getImageByteData(span, ImageByteFormat.rawRgba, textScaleFactor);
  final Size imageSize = imageData.size;
  final ByteData byteData = imageData.byteData;
  final numRows =
      (byteData.lengthInBytes / (bytesPerPixel * imageSize.width)).round();
  int foundRow;
  /// Scan each pixel from bottom to top keeping track of the row
  for (int row = numRows - 1; row >= 0 && foundRow == null; row--) {
    final int rowLength = bytesPerPixel * imageSize.width.round();
    final int startRowByteIndex = row * rowLength;
    /// Only looking at first byte of each pixel is good enough
    for (int byteArrayIndex = startRowByteIndex;
        byteArrayIndex < row * rowLength + rowLength;
        byteArrayIndex += bytesPerPixel) {
      final int byteValue = byteData.getUint8(byteArrayIndex);
      /// The background is white so look for a non-white pixel.
      if (foundRow == null && byteValue != 0xff) {
        foundRow = row;
        break;
      }
    }
  }
  final double foundRowIndex = foundRow == null ? 0 : foundRow.toDouble();
  final int heightAsZeroBasedIndex = imageSize.height.round() - 1;
  final double paddingValue = heightAsZeroBasedIndex - foundRowIndex;
  return paddingValue;
}

Future<ImageData> _getImageByteData(final TextSpan span,
    final ImageByteFormat byteFormat, final double textScaleFactor) async {
  final painter = TextPainter(
      text: span,
      textDirection: TextDirection.ltr,
      textScaleFactor: textScaleFactor);
  painter.layout();
  final imageData = ImageData();
  imageData.size = Size(painter.width, painter.height);
  final recorder = PictureRecorder();
  final screen = Offset.zero & imageData.size;
  final canvas = Canvas(recorder);
  drawBackground(canvas, screen);
  painter.paint(canvas, Offset.zero);
  final picture = recorder.endRecording();
  final image =
      await picture.toImage(screen.width.round(), screen.height.round());
  final ByteData byteData = await image.toByteData(format: byteFormat);
  imageData.byteData = byteData;
  return imageData;
}

void drawBackground(final Canvas canvas, final Rect screen) {
  canvas.drawRect(
      screen,
      Paint()
        ..color = Colors.white
        ..style = PaintingStyle.fill);
}

class TopBottomPadding {
  double top;
  double bottom;

  TopBottomPadding(this.top, this.bottom);
}

class ImageData {
  ByteData byteData;
  Size size;
}

This solution works for any screen density, font size, or text scale factor.

How to align content of a div to the bottom using CSS, position:relative;. } .gfg {. font-size:40px;. color:green;. font-weight:bold;. tect-align: center. } .geeks {. text-align:center;. } #bottom {. position:absolute;. bottom:0;. Text Alignment. The text-align property is used to set the horizontal alignment of a text.. A text can be left or right aligned, centered, or justified. The following example shows center aligned, and left and right aligned text (left alignment is default if text direction is left-to-right, and right alignment is default if text direction is right-to-left):

Aligning an element to the bottom of its container, Here is a little CSS trick that allows you to align content to the bottom of aligned to its top right corner, and a caption aligned to its bottom right� The align-self property accepts all of the same values as align-items plus a value of auto, which will reset the value to that which is defined on the flex container. In this next live example, the flex container has align-items: flex-start , which means the items are all aligned to the start of the cross axis.

CSS: centering things, CSS has the property 'text-align' for that: div.container3 { height: 10em; position : relative } /* 1 */ div.container3 p { margin: 0; position: absolute; /* 2 */ top: 50%;� Set the position for the parent to "relative", and for the child, set it to "absolute". Set the top, bottom, left, and rightproperties for the child. Set the margin to "auto" to make all margins equal and make the child <div> to be centered vertically as well as horizontally. Example of vertically aligning a text with the CSS position property:¶

13 ways to vertical center, Whether we were trying to align an icon or image beside the text, create When the element has intrinsic dimensions we might use 0 for top and bottom, . container{ display: flex; } .element{ align-self: center; margin: 0 auto; }. With CSS grid layout, the grid itself within its container as well as grid items can be positioned with the following 6 properties: justify-items, align-items, justify-content, align-content, justify-self and align-self.

Comments
  • in your Column add - mainAxisSize: MainAxisSize.min,
  • Padding is creating the allusion of alignment with the words, right?
  • Yes, If we remove the padding around red Container - it won't baseline with Text.
  • How do I calculate the values for EdgeInsets so that it adjusts if the text size changes?
  • divide the fontSize with common value to get padding value. - here that value is 4.2 - updated the answer with same.
  • Trick is to pass the fontSize value to directly TextStyle & in EdgeInsets/4.2 & EdgeInsets/4.5. As FontSize variable increases Padding decreases auto. so ratio is same always.