fix: Add comprehensive width constraints to NativeWebView CSS

Added multiple CSS rules to prevent content overflow:

Universal rules:
- * { max-width: 100%; box-sizing: border-box; }

HTML/Body:
- overflow-x: hidden on both html and body
- width: 100% to enforce viewport width
- word-wrap and overflow-wrap: break-word on body

Pre blocks:
- max-width: 100%
- white-space: pre-wrap (allows wrapping)
- word-wrap: break-word

Viewport meta:
- Added maximum-scale=1.0, user-scalable=no to prevent zooming issues

The native iOS 26+ WebView handles width differently than WKWebView,
requiring explicit overflow and width constraints in CSS.
This commit is contained in:
Ilyas Hallak 2025-10-10 20:18:38 +02:00
parent 615abf1d74
commit 4c744e6d10
3 changed files with 20 additions and 6 deletions

View File

@ -115,6 +115,7 @@ struct BookmarkDetailLegacyView: View {
} }
} }
.coordinateSpace(name: "scrollView") .coordinateSpace(name: "scrollView")
.clipped()
.ignoresSafeArea(edges: .top) .ignoresSafeArea(edges: .top)
.scrollPosition($scrollPosition) .scrollPosition($scrollPosition)
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in .onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in

View File

@ -46,6 +46,7 @@ struct BookmarkDetailView2: View {
// Main scroll content // Main scroll content
scrollViewContent scrollViewContent
} }
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
toolbarContent toolbarContent
@ -100,20 +101,15 @@ struct BookmarkDetailView2: View {
VStack(spacing: 0) { VStack(spacing: 0) {
ZStack(alignment: .top) { ZStack(alignment: .top) {
// Header image (in background)
headerView headerView
// Content (in foreground)
VStack(alignment: .leading, spacing: 16) { VStack(alignment: .leading, spacing: 16) {
// Spacer for header
Color.clear.frame(width: geometry.size.width, height: viewModel.bookmarkDetail.imageUrl.isEmpty ? 84 : headerHeight) Color.clear.frame(width: geometry.size.width, height: viewModel.bookmarkDetail.imageUrl.isEmpty ? 84 : headerHeight)
// Title section
titleSection titleSection
Divider().padding(.horizontal) Divider().padding(.horizontal)
// Jump to last position button
if showJumpToProgressButton { if showJumpToProgressButton {
jumpButton(containerHeight: geometry.size.height) jumpButton(containerHeight: geometry.size.height)
} }

View File

@ -108,9 +108,19 @@ struct NativeWebView: View {
let styledHTML = """ let styledHTML = """
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="color-scheme" content="\(isDarkMode ? "dark" : "light")"> <meta name="color-scheme" content="\(isDarkMode ? "dark" : "light")">
<style> <style>
* {
max-width: 100%;
box-sizing: border-box;
}
html {
overflow-x: hidden;
width: 100%;
}
body { body {
font-family: \(fontFamily); font-family: \(fontFamily);
line-height: 1.8; line-height: 1.8;
@ -122,6 +132,10 @@ struct NativeWebView: View {
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
-webkit-user-select: text; -webkit-user-select: text;
user-select: text; user-select: text;
overflow-x: hidden;
width: 100%;
word-wrap: break-word;
overflow-wrap: break-word;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -169,6 +183,9 @@ struct NativeWebView: View {
padding: 16px; padding: 16px;
border-radius: 8px; border-radius: 8px;
overflow-x: auto; overflow-x: auto;
max-width: 100%;
white-space: pre-wrap;
word-wrap: break-word;
font-family: 'SF Mono', monospace; font-family: 'SF Mono', monospace;
} }