Skip to content

Instantly share code, notes, and snippets.

@futurepaul
Last active August 19, 2019 01:04
Show Gist options
  • Save futurepaul/a82cf17d3bde103505261d53a54b30b1 to your computer and use it in GitHub Desktop.
Save futurepaul/a82cf17d3bde103505261d53a54b30b1 to your computer and use it in GitHub Desktop.
how to make a button

SCENARIO 1: BUTTON WIDTH IS BASED ON LABEL WIDTH

I want the width of the button to be: padding_left + label_width + padding_right

I want the height of the button to be: padding_top + label_height + padding_bottom

I want the label centered horizontally and vertically

In CSS this would be:

#button {
  display: inline-block;
  background-color: black;
  padding: 10px;
}

#label {
  color: white;
}
<div id="button>
  <div id="label">Label text</div>
</div>

In Swift UI this would be:

HStack {
  Text("Label text").color(Color.white).padding(10.0)
}.background(Color.black)

SCENARIO 2: BUTTON HAS ITS OWN WIDTH

The width of the button is predefined.

I want the height of the button to be: padding_top + label_height + padding_bottom

I want the label centered horizontally and vertically: label_middle = (button_width - label_width) / 2

In CSS:

#button_has_width {
  width: 200px;
  display: flex;
  justify-content: center;
  padding-top: 10px;
  padding-bottom: 10px;
}

Swift:

HStack {
  Text("Label text").color(Color.white).frame(width: 200.0).padding(.vertical, 10.0)
}.background(Color.black)

SCENARIO 3: BUTTON HAS ITS OWN WIDTH AND HEIGHT

HStack {
  Text("Label text").color(Color.white).frame(width: 200.0, height: 30.0)
}.background(Color.black)

SCENARIO 4: LABEL IS ALIGNED TOP-LEFT IN BUTTON

#button_top_left_label {
  display: flex;
  justify-content: left;
  align-items: flex-start;
  width: 200px;
  height: 30px;
  background-color: black;
}
HStack {
  Text("Label text").color(Color.white).frame(width: 200.0, height: 30.0, alignment: .topLeading)
}.background(Color.black)
@raphlinus
Copy link

raphlinus commented Aug 19, 2019

Looks like you may have figured this out, but here's my analysis:

Scenario 1

Container of button provides 0 minimum size.

Button owns Padding owns Label

Scenario 2

Container of button provides tight constraint for width, 0 min for height.

Button owns Center owns Padding owns Label

The Padding only applies vertical padding. (I think the order of Center and Padding also doesn't matter here)

See below for implementation details of Center.

Scenario 3

Container of button provides tight constraint.

Button owns Center owns Label

The Center works the same as Flutter. I think that's passing down the max constraint unmodified, setting min to 0, then centering its child's layout.

Flutter source for reference is widgets/basic.dart. Center is a subclass of Align, but the actual RenderObject is RenderPositionedBox (in rendering/shifted_box.dart). I believe the actual impl uses the loosen method in BoxConstraints.

Scenario 4

I think this is basically similar to Center but using (0, 0) for the child's layout rather than (delta_width / 2, delta_height / 2). I think this is the Align widget in Flutter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment