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

Add support for auto horizontal margins #879

Conversation

zbarbuto
Copy link
Contributor

@zbarbuto zbarbuto commented Oct 25, 2021

Adds support for margin: auto style centering.

A pretty common centering pattern in HTML/CSS is to give a left and right margin value of auto. Further, some WYSIWYG editors that output HTML will use this to center content like images instead of text-align.

As a basic example:

<p> This is some pre-text</p>
<div style="width: 150px; margin: auto; background-color: salmon;">I am centered!</div>
<p> This is some post-text</p>

Typically renders as (screenshot is from Chrome):

image

This PR adds support for margin: auto by changing margin storage from plain EdgeInsets to a new Margins class which wraps left, top, right, and bottom Margin values. This allows storing a raw double value as before but also to flag the particular edge as auto allowing it to be wrapped in a Row to center it if needed.

I have updated the example project with a few samples:

      <div style="width: 150px; height: 20px; background-color: red; margin: auto;">Centered Div</div>
      <div style="width: 150px; height: 20px; background-color: yellow; margin-left: auto;">margin-left: auto div</div>

Both of which now render as expected (screenshot is on an iPad):

image

FTR I assume ContainerSpan forms the wrapper for most elements so this would also make it work for things like img?

if(style.margin?.isAutoHorizontal ?? false) {
return Row(
mainAxisAlignment: style.margin?.alignment ?? MainAxisAlignment.start,
children: [Flexible(child: container)],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have added this flexible wrapper so we don't run into issues when text overflows inside a centered div:

(blue is fixed width, red is non-fixed width, both using margin: auto)

image

@zbarbuto
Copy link
Contributor Author

zbarbuto commented Oct 25, 2021

Sadly doesn't seem to work with images - any advice on what I need to change to support this? Would applying the same wrapper in _recursiveLexer be the best place?

@zbarbuto
Copy link
Contributor Author

zbarbuto commented Nov 5, 2021

Sorry for the ping @erickok but do you have any feedback here and/or any advice for the best way I can make this work for inline images as well?

@erickok
Copy link
Collaborator

erickok commented Nov 5, 2021

This isn't so easy to achieve I suspect but I haven't had time to take a deep dive into it due to time limitations on my side.

@zbarbuto
Copy link
Contributor Author

zbarbuto commented Nov 8, 2021

I managed to get it working for images as well with a few tweaks:

image

Turns out there was a bug in the image renderer which wasn't passing the correct context (and, hence, styles) to the image which I have pull requested separately as #886

Copy link
Collaborator

@tneotia tneotia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also when #924 is merged, there will likely be conflicts to resolve, you should be able to use the same approach as an extension on EdgeInsets to ensure non-negative values.

lib/src/css_parser.dart Outdated Show resolved Hide resolved
@zbarbuto zbarbuto force-pushed the feature/auto-margins branch 2 times, most recently from 3d961b4 to 822d16e Compare December 8, 2021 21:30
@zbarbuto
Copy link
Contributor Author

zbarbuto commented Dec 8, 2021

Have rebased on latest master.

@zbarbuto
Copy link
Contributor Author

zbarbuto commented Dec 8, 2021

The Dart auto-formatter seems to have been a bit aggressive - is there a custom print-width I need to use or something to avoid the extra unnecessary diffs?

@erickok
Copy link
Collaborator

erickok commented Dec 9, 2021

Unfortunaly over time we seem to have used different formatting standards (including line width) and I fear any application of a since format now would cause code changes. We should really do that one time.

@tneotia
Copy link
Collaborator

tneotia commented Dec 9, 2021

Yeah the formatter did go a bit crazy, especially in the most recent commit. I would suggest turning off auto format in VSCode and either clearing the current branch of its changes, or creating a new PR with the core changes (formatting left out).

Also this would be a breaking change in our library API as the style param would now take Margin instead of EdgeInsets.

@tneotia
Copy link
Collaborator

tneotia commented Dec 16, 2021

@zbarbuto due to all changes from the customRender PR, there are conflicts that need to be resolved now, just FYI

@zbarbuto
Copy link
Contributor Author

@tneotia No problems.

Please leave this PR open for now and hopefully I'll have some time this week rebase on master without the auto-format changes rather than make a new one.

@zbarbuto
Copy link
Contributor Author

@tneotia Ok I've cleaned the diffs and fixes a few issues that were inconsistent with normal HTML behaviour. The demo has been updated to show these edge-cases:

image

I previously was always center-aligning images that had auto horizontal margins but normal behaviour is to only do this if they are explicitly display: block (I'm guessing images are implicitly inline-block)

@zbarbuto
Copy link
Contributor Author

Whoops - typo in the fuschia example - fixed:

image

lib/image_render.dart Outdated Show resolved Hide resolved
Copy link
Collaborator

@tneotia tneotia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nit, otherwise LGTM!

tneotia
tneotia previously approved these changes Dec 23, 2021
Copy link
Collaborator

@tneotia tneotia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice work! Hopefully we can include this in the massively breaking v3.0.0... I also anticipate you'll have to do yet another rebase of this branch once #661 is merged...

@tneotia
Copy link
Collaborator

tneotia commented Jan 6, 2022

@zbarbuto #661 is merged, I promise this will be the last conflict resolve you have to do :)

Allow centering images with auto-margins
@zbarbuto
Copy link
Contributor Author

zbarbuto commented Jan 10, 2022

I have rebased and applied my changes. There is an issue that has come up after rebase in that divs are not displaying as block-level correctly which breaks their alignment (see the coloured examples below):

image

For now, I am considering fixing this outside the scope of this pull request as it is currently broken on master anyway. i.e. the following:

      <div style="width: 150px; height: 20px; background-color: #ff9999;">Div A</div>
      <div style="width: 150px; height: 20px; background-color: #99ff99;">Div B</div>
      <div style="width: 150px; height: 20px; background-color: #ff99ff;">Div C</div>

Renders in a blank project using flutter_html as:

image

But in regular HTML e.g. in a CodePen as:

image

If this issue is fixed independently the alignment feature of this pull request should work as expected.

@zbarbuto
Copy link
Contributor Author

zbarbuto commented Feb 7, 2022

@tneotia sorry for the ping but anything further I need to do on this since it has been rebased?

I can create a separate issue for the block display problem above?

@tneotia
Copy link
Collaborator

tneotia commented Feb 12, 2022

Sure I would create a separate issue. I don't think anything more needs to be done, just @erickok needs to review.


bool get isAutoHorizontal => (left is AutoMargin) || (right is AutoMargin);

Alignment? get alignment {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like where we're going with this PR, but I'm not sure how I feel about the margin class handling its own alignment. I'm sure there are edge cases where these alignments don't hold true.

For now, can we move this alignment calculation outside of the Margins class?

I'm also going to look into how the w3 says renderers should handle auto margins for inspiration.

Thank you!

@Sub6Resources Sub6Resources changed the base branch from master to enhancement/margin-values August 20, 2022 23:31
@Sub6Resources
Copy link
Owner

Merging this into a new branch enhancement/margin-values so I can continue refinements and get it merged in

@Sub6Resources Sub6Resources merged commit 65dbe79 into Sub6Resources:enhancement/margin-values Aug 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants