12

I am building a Mac application using Swift. Therefor, I want to make a WKWebView transparent, so it shows the text of the loaded HTML, but the background of my underlaying NSWindow is visible. I tried

webView.layer?.backgroundColor = NSColor.clearColor().CGColor;

which hadn't any effect. WKWebView inherits from NSView, but I don't know if this helps.

Another solution would be to insert a NSVisualEffectView as the background of the WebView, but I don't know how to accomplish that, either!

danielbuechele
  • 3,104
  • 2
  • 18
  • 29

5 Answers5

28

Use this in macOS 10.12 and higher:

webView.setValue(false, forKey: "drawsBackground")
Ely
  • 8,259
  • 1
  • 54
  • 67
9

It was not supported, then they fixed it:

https://bugs.webkit.org/show_bug.cgi?id=134779

The way to make it transparent is to:

myWebView.opaque = false
AJ Venturella
  • 4,742
  • 4
  • 33
  • 62
5

Code below works for me perfectly, also color is set to clearColor by default.

[wkWebView setValue:YES forKey:@"drawsTransparentBackground"];
kisileno
  • 787
  • 9
  • 23
  • 1
    SetValue:YES is disallowed with ARC. [NSNumber numberWithBool:YES] should be use. And also there is no key value coding-compliant drawsTransparentBackground for the WKWebView – Onder OZCAN Jun 01 '15 at 08:50
  • 1
    So this _does_ work when called correctly: `[wkWebView setValue:@(YES) forKey:@"drawsTransparentBackground"];` (note the `@(YES)`; Inna's `[NSNumber numberWithBool:YES]` is equivalent). The view is KVC compliant for this key at least on 10.11; it triggers the internal method `_setDrawsTransparentBackground:`. – DarkDust Feb 18 '16 at 12:46
  • Also, at least the `WKWebView`'s parent view must be layer-backed or layer-hosted. In a non-layered environment you get strange results (window is completely transparent where the web view is transparent; you do not see the views below the web view). – DarkDust Feb 18 '16 at 12:48
4

I used this for macOS 10.12. without problems in OjbC:

[self.webView setValue:@YES forKey:@"drawsTransparentBackground"];

Under macOS 10.13.+ I got the following console warning message:

-[WKWebView _setDrawsTransparentBackground:] is deprecated and should not be used

The ONLY working solution was:

[self.webView setValue:@(NO) forKey:@"drawsBackground"];

I tried the below in many scenarios and it didn't work:

  • give the webView and the enclosingScrollView a layer and edit it's properties (backgroundColor, isOpaque)
  • give the webView and the enclosingScrollView a clear background color
  • inject javascript without the setValue forKey: in the webview.

Additionally I did use:

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
    if (self.isWebviewsBackgroundTransparent) {
        [self insertTransparentBackgroundTo:webView];
    }
}

- (void)insertTransparentBackgroundTo:(WKWebView *)webView
{
    NSString *transparentBackgroundJSSString = @"document.body.style = document.body.style.cssText + \";background: transparent !important;\";";
    [webView evaluateJavaScript:transparentBackgroundJSSString completionHandler:nil];
}
Darkwonder
  • 1,149
  • 1
  • 13
  • 26
2

Updated, slightly better solution (2022). There is a private property drawsBackground on WKWebViewConfiguration. This property has been introduced in macOS 10.14 so it won't go away.

//https://opensource.apple.com/source/WebKit2/WebKit2-7610.2.11.51.8/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h.auto.html


//One can verify that the property still exists: 
//https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h
@property (nonatomic, setter=_setDrawsBackground:) BOOL _drawsBackground WK_API_AVAILABLE(macos(10.14), ios(12.0));

Example:

let configuration = WKWebViewConfiguration()
var requiresDrawBackgroundFallback = false
if #available(OSX 10.14, *) {                         
    configuration.setValue(false, forKey: "sward".reversed() + "background".capitalized) //drawsBackground KVC hack; works but private
} else {
    requiresDrawBackgroundFallback = true
}
let webView = WKWebView(frame: .zero, configuration: configuration)
if requiresDrawBackgroundFallback {
    webView.setValue(false, forKey: "sward".reversed() + "background".capitalized) //drawsBackground KVC hack; works but private
}
Marek H
  • 5,173
  • 3
  • 31
  • 42