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

Support for flexible row heights based on content size #2342

Open
charliesneath opened this issue Jan 9, 2025 · 3 comments
Open

Support for flexible row heights based on content size #2342

charliesneath opened this issue Jan 9, 2025 · 3 comments
Labels
bug Existing features not working as expected

Comments

@charliesneath
Copy link

charliesneath commented Jan 9, 2025

Context

I have a program that will automatically generate page layouts given images in different orientations across an arbitrary number of rows and columns. A common case is 2 landscape images in a single column, or maybe a single portait-orientation photo. Chrome can handle this very well with flexbox and I've had good success generating the templates on the backend and having the layouts rendered as expected on the front-end.

Here's a screenshot from Chrome of a few layout variations using some simple placeholder images:

Image

However, when exporting these layouts to PDF, I've hit the limits of Weasyprint's flex support, so I'm seeing if I can make it work with grid layout...or highlight the issues for the team :)

As shown below, Weasyprint can't render these layouts at all; I assume this is because grid display is still work-in-progress, but I have a hunch that Chrome is more forgiving that Weasyprint and I'll need some additional code in the CSS; I'm just not sure what doesn't work because grid display is in-progress, or lazy CSS on my part.

Layout A

The first row has 2 landscape photos that fill the max width, allowing the second row the fill the remaining within the layout on the page.

Image

Layout B

For comparison, here's the same layout, but with a single horizontal photo in the first column. As expected, the first row takes up more horizontal space and the layout accommodates accordingly.

Image

Weasyprint: Layout A

Weasyprint chokes on Layout A. The code is shown below.

Image

Layout A

<div class="container"> 
  <div class="layout">
    <div class="row">
      <img src="landscape.png" />
      <img src="landscape.png" />
    </div>
    <div class="row">
      <img src="portrait.png" />
    </div>
  </div>
</div>

CSS

.container {
  width: 500px;
  aspect-ratio: 8.5/11;
  background-color: black;
  display: flex;
  padding: 50px;
  box-sizing: border-box;
  flex-direction: column;

  .layout {
    flex: 1;
    display: grid;
    padding: 50px;
    background-color: white;
    min-height: 0;

    .row {
      display: flex;
      flex-direction: row;
      border: 1px dashed black;
      justify-content: center;
      min-height: 0;
      padding: 20px;
      gap: 1rem;

      img {
        object-fit: contain;
        max-height: 100%;
        max-width: 100%;
        min-height: 0;
        min-width: 0;
        border: 1px solid black;
      }
    }
  }
}

Layout C

I can generate something vaguely similar to Layout A if I swap the images for div's with fixed height/width, but this isn't very useful as the images have fixed heights that I want the grid rows to adjust to.

CSS

...
      .item {
        max-height: 100%;
        max-width: 100%;
        min-height: 0;
        min-width: 0;
        border: 1px solid black;
	width: 100px;
	height: 100px;
      }
...

HTML

<div class="container">
  <div class="layout">
    <div class="row">
      <div class="item"></div>
      <div class="item"></div>
    </div>
    <div class="row">
      <div class="item"></div>
    </div>
  </div>

Chrome Output

Image

Weasyprint Output

Image
@charliesneath charliesneath changed the title Support for flexible row heights Support for flexible row heights based on content size Jan 9, 2025
@liZe
Copy link
Member

liZe commented Jan 10, 2025

Hi!

There are many reasons why WeasyPrint doesn’t give the right rendering, mainly:

Hopefully, none of them are related to grid layout, whose support is much more solid than flex in WeasyPrint, even if it’s not complete (see #2145).

With minor changes to the CSS (set height on .container and display: block to img), here’s what I can get:

Image

An image is obviously missing from the rendering (because of the quite bad support of flex), but at least we can see the overall layout.

Even if your example is probably a combination of other flex layout problems already reported, let’ keep this issue open because your examples are great!

(And here’s a secret: we’ll be soon working on flex really hard, so… Stay tuned!)

@liZe liZe added CSS Questions about how to do something with CSS bug Existing features not working as expected and removed CSS Questions about how to do something with CSS labels Jan 10, 2025
@charliesneath
Copy link
Author

charliesneath commented Jan 14, 2025

@liZe Thanks for a thoughtful response! I'm glad the examples are helpful and great to hear flex improvements are coming :)

After putting the above example together, I realized how little it actually uses CSS grid. I've put together a similar example using only grid to demonstrate differences between what I'm seeing in Chrome vs. what Weasyprint outputs for a PDF.

I'll include the updated example here, but happy to also create a new issue if that's easier.

The difference in approach is as follows:

  • The .container is a grid with a single row and column
  • The .layout has a single column with a dynamic number of rows (3 in this example)
  • Each .row is a grid with a single row, but a number of columns equal to the number of children photos/images

My expectation is that the .row heights adjust to the size of the content, since they will be different sizes depending on the orientation of images on this page.

(Note that I'm hard-coding the grid-template-columns value for the .rows in this example, but I would just use some CSS variables with the template to make this dynamic.)

Here's a view leveraging Chrome's grid inspector:

Image

Chrome Output

Image

Weasyprint Output

I might be missing a few lines of CSS to make this snap into place, but here's the output I'm getting currently.

Image

CSS


.container {
  display: grid;
  width: 500px;
  height: 600px;
  background-color: black;
  padding: 50px;
  box-sizing: border-box;

  .layout {
    display: grid;
    padding: 50px;
    background-color: white;
    min-height: 0;

    .row {
      display: grid;
      border: 1px dashed black;
      justify-content: center;
      min-height: 0;
      min-width: 0;

      &#row-1 {
	grid-template-columns: 1fr 1fr;
      }

      &#row-2 {
	grid-template-columns: 1fr;    
      }

      &#row-3 {
        grid-template-columns: 1fr;
      }

      .cell {
        max-height: 100%;
        max-width: 100%;
        min-height: 0;
        min-width: 0;
        border: 1px solid black;

	&.portrait {
	  background-color: lightgreen;
	}

	&.landscape {
	  background-color: lightblue;
	}
      }

      img {
        object-fit: contain;
        max-height: 100%;
        max-width: 100%;
        min-height: 0;
        min-width: 0;
        border: 1px solid black;
	height: 100%;
	width: 100%;
	display: block;
      }
    }
  }
}

HTML

<div class="container grid">
  
  <div class="layout">

    <div class="row" id="row-1">
      <div class="cell"><img src="{% static 'images/landscape.png' %}" /></div>
      <div class="cell"><img src="{% static 'images/landscape.png' %}" /></div>
    </div>

    <div class="row" id="row-2">
      <div class="cell"><img src="{% static 'images/portrait.png' %}" /></div>
    </div>
    
    <div class="row" id="row-3">
      <div class="cell"><img src="{% static 'images/landscape.png' %}" /></div>
    </div>
    
  </div>
  
</div>

@liZe
Copy link
Member

liZe commented Jan 18, 2025

Could you please open a separate issue for this bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

2 participants