display flex is breaking UI
Using Django with Bootstrap 5 for CSS. Here is the HTML to produce the card design
{% load static %}
<html lang="en">
<head>
<title>Attempt Response</title>
<link href="{% static 'pdf_report/assets/css/styles.css' %}" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="card my-3">
<div class="card-header bg-gradient-light text-dark p-3 d-flex align-items-center justify-content-between">
<div class="card-title text-bold mb-0 d-flex">
<div class="me-1">3.</div>
<div>
<div class="question">
Select the following that does not affect rate of evaporation?
</div>
<div class="d-flex">
<div class="bg-primary text-xxs text-white px-2 py-1 rounded text-bolder me-1">
Subject: Science
</div>
<div class="bg-primary text-xxs text-white px-2 py-1 rounded text-bolder">
Multiple choice
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="answer-preview">
<div class="preview-multiple-choice blockquote ps-2 mb-0 py-2 fs-6">
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
id="input-iwslt1"
type="radio"
value="" name="a" checked>
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-iwslt1">
Temperature
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
id="input-f84gw3"
type="radio"
value="" name="a">
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-f84gw3">
Surface area
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input ng-untouched ng-pristine"
disabled=""
id="input-zy80v2"
type="radio"
value="">
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-zy80v2">
Wind speed
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
type="radio">
<label class="custom-control-label mb-0 ms-1 mt-1 text-success" for="input-ckk0hk">
Insoluble heavy impurities
</label>
</div>
</div>
</div>
</div>
<div class="card-footer d-flex justify-content-between align-items-center bg-light py-2">
<div class="d-flex">
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder me-1"> Time Spent: 8 sec.</div>
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder me-1"> 1 Attempt</div>
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder"> Timeout</div>
</div>
<div>
</div>
</div>
</div>
</div>
</body>
</html>
and the python code as
template_path = 'template1.html'
template = get_template(template_path)
html = template.render({})
css_file = 'styles.css'
page_css = CSS(
string='''
@page {
size: A4;
margin: 1cm;
}'''
)
stylesheets = [page_css]
css = CSS(filename=css_file)
stylesheets.append(css)
pdf_file = HTML(string=html).write_pdf(
stylesheets=stylesheets, optimize_images=True, jpeg_quality=60, dpi=150
)
response = HttpResponse(pdf_file, content_type='application/pdf')
response['Content-Disposition'] = 'filename="home_page.pdf"'
return response
I'm expecting it to look like the below screenshot
But the pdf rendered has too much space and space breaking. Event text overflowing on longer strings.
Removing d-flex (display flex), solves a few of the issues.
Hi!
Thanks for your report.
Flex support in WeasyPrint is know to be quite bad in many cases, there are many open issues about that 😒. We want to rewrite the whole Flex module, but it would require a lot of time / money that we didn’t find yet, unfortunately. We’re currently quite busy on other topics (including Grid layout 🚀, which is much more solid that Flex), but we hope that we’ll find the resources to solve all these dirty Flex bugs in the future.
Is it possible to supply the actual HTML and CSS for the example?
This may be partially fixed by #2231 but I have no way to test it since I don't have access to your Django/Bootstrap/etc/etc/etc/ setup.
It’s only partially fixed. Here’s a full HTML example:
<html lang="en">
<head>
<title>Attempt Response</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="card my-3">
<div class="card-header bg-gradient-light text-dark p-3 d-flex align-items-center justify-content-between">
<div class="card-title text-bold mb-0 d-flex">
<div class="me-1">3.</div>
<div>
<div class="question">
Select the following that does not affect rate of evaporation?
</div>
<div class="d-flex">
<div class="bg-primary text-xxs text-white px-2 py-1 rounded text-bolder me-1">
Subject: Science
</div>
<div class="bg-primary text-xxs text-white px-2 py-1 rounded text-bolder">
Multiple choice
</div>
</div>
</div>
</div>
</div>
<div class="card-body p-3">
<div class="answer-preview">
<div class="preview-multiple-choice blockquote ps-2 mb-0 py-2 fs-6">
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
id="input-iwslt1"
type="radio"
value="" name="a" checked>
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-iwslt1">
Temperature
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
id="input-f84gw3"
type="radio"
value="" name="a">
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-f84gw3">
Surface area
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input ng-untouched ng-pristine"
disabled=""
id="input-zy80v2"
type="radio"
value="">
<label class="custom-control-label mb-0 ms-1 mt-1 text-" for="input-zy80v2">
Wind speed
</label>
</div>
<div class="form-check d-flex align-items-center me-2">
<input class="form-check-input"
disabled=""
type="radio">
<label class="custom-control-label mb-0 ms-1 mt-1 text-success" for="input-ckk0hk">
Insoluble heavy impurities
</label>
</div>
</div>
</div>
</div>
<div class="card-footer d-flex justify-content-between align-items-center bg-light py-2">
<div class="d-flex">
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder me-1"> Time Spent: 8 sec.</div>
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder me-1"> 1 Attempt</div>
<div class="bg-dark text-xxs text-white px-2 py-1 rounded text-bolder"> Timeout</div>
</div>
<div>
</div>
</div>
</div>
</div>
</body>
</html>
We’re almost done with this issue! The only problem left is the width of the radio buttons.
(For the record: the numbers transformed into emojis are caused by the font names with "emoji" in the --bs-font-sans-serif variable. I have the same problem with some, but not all, browsers on my system, because Fontconfig is configured to use colored emojis if possible.)
Bug is closed and tested in the flex branch, see https://github.com/Kozea/WeasyPrint/issues/2362.