Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vertical content alignment in containers #134

Closed
6 tasks done
andrewleader opened this issue Mar 3, 2017 · 25 comments
Closed
6 tasks done

Vertical content alignment in containers #134

andrewleader opened this issue Mar 3, 2017 · 25 comments
Assignees

Comments

@andrewleader
Copy link
Contributor

andrewleader commented Mar 3, 2017

Implementation status

Problem

Currently, it's not possible to vertical align content within a column (or within a fixed height container like Timeline). Without vertical alignment on the body and containers itself, you won't be able to achieve things like this...

image

Instead it would look like...

image

Design

Add a new verticalContentAlignment property to Container, Column, and AdaptiveCard:

Property name Type Description
verticalContentAlignment string. Allowed values are "top" (default), "center", and "bottom". Defines how the content should be aligned vertically within the container. "top" indicates that content should be placed at the top. "center" and "bottom" function the same other than simply placing at center or at bottom.

Because we are introducing a "height" property, it makes sense to also rename the "size" property of a Column to "width"

Example

Card payload

{
	"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
	"type": "AdaptiveCard",
	"version": "1.1",
	"verticalContentAlignment": "center",
	"body": [
		{
			"type": "TextBlock",
			"text": "Hi,"
		},
		{
			"type": "TextBlock",
			"text": "MasterHip",
			"isSubtle": true
		}
	]
}
@matthidinger
Copy link
Member

Agree we should add it to Column, need to think more about the container card

@matthidinger matthidinger added this to the v1 milestone Jul 6, 2017
@matthidinger matthidinger modified the milestones: v1.1, v1 Aug 11, 2017
@matthidinger
Copy link
Member

Duplicate of #484

@matthidinger matthidinger marked this as a duplicate of #484 Sep 15, 2017
@andrewleader andrewleader reopened this Oct 30, 2017
@andrewleader andrewleader changed the title Vertical alignment missing Vertical alignment support Oct 30, 2017
@khouzam khouzam removed this from the v1.1 milestone Nov 30, 2017
@mollyd26 mollyd26 added the Epic label Jan 11, 2018
@dclaux dclaux changed the title Vertical alignment support Vertical content alignment in containers Apr 4, 2018
@almedina-ms
Copy link
Contributor

almedina-ms commented May 21, 2018

@Anbare @dclaux @matthidinger What's the difference or what should be different in the behaviour of stretch and top? We currently have stretch for the height property for each element (#484) and this property is supposed to act on all children of a container

@dclaux
Copy link
Member

dclaux commented May 21, 2018

@almedina-ms actually there is no stretch. The spec is out of date. Valid values are top, center and bottom, and the default is top.

@dclaux
Copy link
Member

dclaux commented May 21, 2018

I have updated the spec.

@andrewleader
Copy link
Contributor Author

@dclaux @matthidinger I don't think we ever agreed to NOT have stretch as an option. We need to discuss this one, unless the API board has actually already discussed this offline without discussing it here?

The email thread we had on this left off with no conclusion (we didn't get any feedback on it outside of just David and myself).

@dclaux
Copy link
Member

dclaux commented May 22, 2018

@Anbare given we have the height property the stretch value on verticalContentAlignment isn't needed.

@andrewleader
Copy link
Contributor Author

@dclaux I disagree. So we need to have a group consensus, we've already tried convincing each other, it didn't happen.

@almedina-ms
Copy link
Contributor

@Anbare What is the expected behavior for stretch?

@andrewleader
Copy link
Contributor Author

andrewleader commented May 22, 2018

Here's my info I put together on it previously...

We need to decide whether verticalContentAlignment should or should not have a “stretch” value as one of its values (it’ll definitely have “top”, “center”, and “bottom”).

Ultimately, both options are functionally-equivalent, meaning that neither option enables any new scenarios. That means the “stretch” value is technically unnecessary. So this decision is purely about what makes more sense from the API perspective, rather than which one is technically superior.

Option 1: No "stretch" value

  • The default value is "top"

Option 2: "stretch" value

  • The default value is "stretch"

Most of the time, “top” and “stretch” are identical in behavior. It’s only when you also use height: stretch on one of the child elements that there would be a difference.

Therefore, imagine you have a card like the following…

Card
-	Height: (fixed height, like in Timeline)
-	VerticalContentAlignment: ______ (specified in the drawings below)
-	Body
o	Item 1 (height: auto)
o	Item 2 (height: stretch)

If we go with Option 1, then it doesn’t matter what verticalContentAlignment the card author set, since the children content will collectively stretch to fill the height due to that child having a stretch height.

image

  • Essentially, if a child has height: stretch, the verticalContentAlignment property on its parent becomes meaningless.

If we go with Option 2, then when verticalContentAlignment is set to anything except “stretch”, the children with stretch heights will essentially become auto heights, since the children content is no longer collectively stretching to fill the height.

image

  • Essentially, if verticalContentAlignment is set to anything except stretch, its children height properties become meaningless.

So with either option, there's cases where assigning one property will invalidate the other property. It's just a question of which behavior would cause the least confusion.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

@Anbare would you agree that both options allow for the exact same set of layout? Eg there isn't one option that is more powerful than the other, right? Given that, doesn't it make more sense to pick the option that adds the least to the schema?

@andrewleader
Copy link
Contributor Author

I already said that both options are technically equivalent.

That doesn't mean we should only pick the option that adds the least to the schema if the other option is less confusing.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

How is having two ways to do the same thing less confusing? Per what you describe, Container.verticalContentALignment = "stretch" is exactly the same as Container.height = "stretch"
Plus there is some evidence of confusion already, look at @almedina-ms's question: "What is the expected behavior for Stretch"?

@andrewleader
Copy link
Contributor Author

Did you read my big previous post I made? I explicitly showed the behavior of stretch. And I captured both almedina's confusion, and the alternate confusion.

Both options have confusion. We need opinions outside of just us. We've already made our arugments, we're not convincing each other.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

Yes, I did read your post. I am very sorry but what you propose is very confusing. In your own drawings, you can see that the container stretches in all three cases. In fact, there is no aligning a container's content center or bottom without the container itself being stretched to a height that is larger than the sum of the heights of its child elements.

I do not see how option 1 is confusing:

  • You want a container, or any element for that matter, to consume as much vertical space at it can within its parent container? Set its height property to "stretch"
  • You want the collective content of a container to align top, center or bottom? Set that container's verticalContentAlignment property

What you propose just adds a way to do the same thing as setting a container's height property to "stretch." Either that, or I still don't understand what you mean, which to me is a sign that it is inherently confusing.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

I think I got it after re-reading your post a few times. You want the stretch value of the verticalContentAlignment property to be a way to override the height value of the container's elements.

Why would it be better to have verticalContentALignment = stretch override the height property of the containers children, rather than have a child's height = stretch override the value of the parent container's verticalContentAlignment?

@andrewleader
Copy link
Contributor Author

That's exactly the question. One of them gets overridden. We have to decide which should override.

I'm personally drawing experience from XAML. They also have a VerticalContentAlignment property which has Stretch like I've proposed: https://msdn.microsoft.com/en-us/library/system.windows.controls.control.verticalcontentalignment(v=vs.110).aspx

Additionally, I would say that since layout happens from the parents->down, properties at the higher level (verticalContentAlignment) should get precedence (and override) the children properties.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

I fundamentally disagree here. XAML's approach is terribly confusing IMO and I don't see a point in replicating that confusing design. There is no need to have two ways to override things.

Plus consider this case:

  • You have a container who's verticalContentAlignment is set to bottom
  • You add two elements to it; one of them has its height set to "stretch"
  • You see that the verticalContentAlignment isn't respected

What do you do?

  • Set the Container's verticalContentAlignment to stretch? That won't work, because it will act like setting it to top
  • Or remove the height = stretch property on your element?

Bottom line is, verticalContentAlignment = stretch serves the sole purpose of forcing top alignment when some of the children have their height set to stretch.

If you don't want your elements to stretch within a container... don't set their height to stretch.

@andrewleader
Copy link
Contributor Author

In the case you described, Option 2 would work as expected without doing either of the two things you mentioned (the content would all appear at the bottom).

That case is exactly what I visualized in the last picture of my post.

@dclaux
Copy link
Member

dclaux commented May 22, 2018

That's not true, per your own explanations. The verticalContentAlignment is set to bottom. The only way for me to have it honored is to remove the height = stretch property on my elements. Setting verticalContentAlignment to stretch will override the height property of my elements, yes, but they will all be aligned to the top, which isn't what I wanted to start with.

@andrewleader
Copy link
Contributor Author

Please read my lengthy post once again. In my proposal (Option 2) where "stretch" is an option, if you set it to top, center, or bottom, the height property of any children are ignored and are treated as auto heights.

Therefore, in Option 2, setting top, center, or bottom actually does make the items go to the top, center, or bottom, regardless of what the children heights are.

Including the picture once again (Item 2 has a height of stretch in the pictures below)...

image

@dclaux
Copy link
Member

dclaux commented May 22, 2018

I actually think you are not reading me properly.

I am talking about a card I am writing, using the properties I assume are the right ones, and the values for those properties that I believe are the right ones. Essentially I am a developer.

So I want to obtain this:
image

And say that for some reason this is what I wrote:

{
	"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
	"type": "AdaptiveCard",
	"version": "1.0",
	"body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "Very long wrapping text to make the column tall. Very long wrapping text to make the column tall. Very long wrapping text to make the column tall. Very long wrapping text to make the column tall. Very long wrapping text to make the column tall. ",
                            "wrap": true
                        }
                    ]
                },
                {
                    "separator": true,
                    "verticalContentAlignment": "bottom",
                    "items": [
                        {
                            "type": "TextBlock",
                            "height": "stretch",
                            "text": "I want this at the bottom"
                        },
                        {
                            "type": "TextBlock",
                            "text": "I want this at the bottom as well"
                        }
                    ]
                }
            ]
        }
	]
}

How do I fix my payload to make it be what I want? The verticalContentAlignment of my column is already set to bottom. Do I set it to stretch instead? No, because if I do I get this:
image

Clearly it has to be set to bottom. So what do I do? I remove the height = stretch:
image

If this is the way (and it would be the only way) to fix the problem for center and bottom alignment, why would there be another way to do it for top alignment?

@andrewleader
Copy link
Contributor Author

In my proposal (Option 2), the payload you initially provided already works correctly and produces the visual result you're expecting (both text elements appear at the bottom). You don't have to remove the height = stretch (the parent property wins). This is what I illustrated in my lengthy post.

In your proposal (Option 1), yes, you would have to remove the height = stretch (the child property wins).

@dclaux
Copy link
Member

dclaux commented May 22, 2018

I had indeed misread you, multiple times at that. Now I understand, and it definitely makes a lot more sense than what I thought I had understood. But then again, there is no need to add a "stretch" value... the rule can simply be that when the verticalContentAlignment property is omitted the container behaves like it would with verticalContentAlignment = stretch.

I don't think this changes my position though. I think saying height = stretch overrides verticalContentAlignment is just fine. Technically, verticalContentAlignment is still applied for that matter, it's just not visible. It matches the way FlexBox works.

@paulcam206
Copy link
Member

Documentation is done and in the mahiding/site1.1 branch.

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

No branches or pull requests

7 participants