Adding Custom Icons to Divi

This post may contain referral links which may earn a commission for this site

The Divi Theme comes pre-packaged with a selection of icons which can be used with modules such as the blurb module. These icons are "font-icons" provided by Elegant Themes and there is no inbuilt way to add new fonts. Fortunately, there is a way we can work around this to add our own custom icons.

Adding Custom Icons using Divi Booster

My Divi Booster plugin lets you add new icons to the list of built-in icons. This makes them easily available to your modules, with no need to upload the image each time you want to use it. The icons will be available in modules which normally have the option to add an icon, such as the blurb and button modules.

To add custom icons using Divi Booster:

  1. Go to the Divi Booster settings page, then under "Site-wide Settings > Icons > Add custom icons for use in modules" you'll see the option to upload a blurb icon.
  2. Click on "Choose Image" then select the icon you want from the media library (or upload a new one) and then click "Use Image".
  3. Finally save the Divi Booster settings and your icon will now be available to you in the modules icon list.

There isn't a limit on how many icons you can add. However, there is a bit trick to it. You can currently only add one image at a time. When you save the settings, another upload box will appear so you can add another icon. So just save after you upload each icon and you can add as many as you like, e.g.:

In this way, you can add as many icons as you like.

To get rid of an icon, click on the little "X" next to the icon you would like to remove.

Adding Custom Blurb Icons in Divi

It is now possible to add blurb icons directly in Divi, by going into the settings for your blurb module settings and setting "Use Icon" to "No" and then selecting an image to display with your blurb, like so:

Note that the Divi option lets you upload a custom icon to a single blurb module. Note that this is differs from the Divi Booster option which lets you add icons to the icon list (and which are therefore available to all your blurb modules). Depending on your needs one or the other of these may suit you better.

Adding Custom Icons Manually using PHP

Here's how to add custom icons manually via PHP code. 

First, add the following PHP code to your site (e.g. in the functions.php file of your child theme). Be sure to take a backup / test on a staging site before using on a live site. There's a lot of code (adding custom icons is a tricky business), but you can basically ignore it all. The only thing that really matters is the last line, which I explain below.

if (!class_exists('DBDBCustomIcon')) {
	
	class DBDBCustomIcon {
		
		protected $id;
		protected $url;		
		
		public function __construct($id, $url='') {
			$this->id = $id;
			$this->url = $url;
		}
		
		public static function setup() {
			add_action('wp_head', array(__CLASS__, 'outputUserCss'));
			add_action('wp_head', array(__CLASS__, 'outputSharedUserJs'));
			add_action('wp_footer', array(__CLASS__, 'outputVisualBuilderJs'));
		}
		
		public static function outputUserCss() {
			echo '<style>'.self::getUserCss().'</style>';
		}
		
		public static function outputSharedUserJs() {
			echo '<script>'.self::getSharedUserJs().'</script>';
		}
		
		public static function outputVisualBuilderJs() {
			if (function_exists('et_fb_enabled') && et_fb_enabled()) {
				echo '<script>jQuery(function($){'.self::getMutationObserverJs().'});</script>';
			}
		}
		
		public function init() {
			$fontSymbolsPriority = apply_filters('DBDBCustomIcon_font_icon_symbols_priority', 50);
			add_filter('et_pb_font_icon_symbols', array($this, 'addToFontSymbols'), $fontSymbolsPriority);
			add_action('admin_head', array($this, 'outputIconPickerCss'));
			add_action('wp_head', array($this, 'outputIconPickerCssFb'));
			add_action('wp_footer', array($this, 'outputIconUpdateJs'));
			add_action('wp_head', array($this, 'db014_user_css_for_custom_button_icon'));
			add_action('wp_head', array($this, 'db014_user_css_for_custom_button_icons'));
			add_action('wp_head', array($this, 'db014_user_css_for_inline_icons'));
			add_action('wp_head', array($this, 'db014_user_css_for_custom_hover_icon'));
			add_action('wp_head', array($this, 'db014_user_css_to_hide_unwanted_icons'));
		}
		
		function db014_user_css_for_custom_button_icons() { ?>
			<style>
			.et_pb_custom_button_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before, 
			.et_pb_custom_button_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:after {
				background-size: auto 1em;
				background-repeat: no-repeat;
				min-width: 20em;
				height: 100%;
				content: "" !important;
				background-position: left center;
				position: absolute;
				top: 0;
			}
			.et_pb_custom_button_icon[data-icon="<?php esc_attr_e($this->id); ?>"] { 
				overflow: hidden;
			}
			</style>
			<?php
		}

		function db014_user_css_for_inline_icons() { ?>
			<style>
			.et_pb_posts .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before,
			.et_pb_portfolio_item .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before {
				content: '' !important;
				-webkit-transition: all 0.4s;
				-moz-transition: all 0.4s;
				transition: all 0.4s;
			}
			.et_pb_posts .entry-featured-image-url:hover .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"] img,
			.et_pb_portfolio_item .et_portfolio_image:hover .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"] img { 
				margin-top:0px; transition: all 0.4s;
			}
			.et_pb_posts .entry-featured-image-url .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"] img, 
			.et_pb_portfolio_item .et_portfolio_image .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"] img { 
				margin-top: 14px; 
			}
			.et_pb_dmb_breadcrumbs a:first-child .db014_custom_hover_icon {
				position: relative !important;
				left: 0%; 
				transform: none;
				vertical-align: middle;
				margin-right: 8px;
			}
			.et_pb_dmb_breadcrumbs li .db014_custom_hover_icon {
				position: relative !important;
				left: 0%; 
				transform: none;
				vertical-align: middle;
				margin-right: 8px;
				margin-left: 4px;
			}
			</style>
			<?php
		}

		function db014_user_css_for_custom_hover_icon() { ?>
			<style>
			.db014_custom_hover_icon { 
				width:auto !important; 
				max-width:32px !important; 
				min-width:0 !important;
				height:auto !important; 
				max-height:32px !important; 
				min-height:0 !important;
				position:absolute;
				top:50%;
				left:50%;
				-webkit-transform: translate(-50%,-50%); 
				-moz-transform: translate(-50%,-50%); 
				-ms-transform: translate(-50%,-50%); 
				transform: translate(-50%,-50%); 
			}
			</style>
			<?php	
		}

		function db014_user_css_to_hide_unwanted_icons() { ?>
			<style>
			.et_pb_gallery .et_pb_gallery_image .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before,
			.et_pb_blog_grid .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before,
			.et_pb_image .et_pb_image_wrap .et_pb_inline_icon[data-icon="<?php esc_attr_e($this->id); ?>"]:before,
			.et_pb_dmb_breadcrumbs > ol > li > a:first-child[data-icon="<?php esc_attr_e($this->id); ?>"]:before,
			.et_pb_dmb_breadcrumbs > ol > li[data-icon="<?php esc_attr_e($this->id); ?>"]:before
			{ 
				display:none !important; 
			}
			</style>
			<?php
		}
		
		function db014_user_css_for_custom_button_icon() { 
			$id = $this->id;
			$url = $this->url;
			$icon = '.et_pb_custom_button_icon[data-icon="'.esc_html($id).'"]';
			$bg_img = empty($url)?'none':"url('".esc_html($url)."')";
			echo <<<END
			<style>
			$icon:before, 
			$icon:after {
				background-image: $bg_img;		
			}
			</style>
END;

			$is_svg = preg_match('#\.svg(\?[^.]*)?$#', $url);
			if ($is_svg) {
				// IE SVG background-size (as "auto" not supported) 
				// - width = half the 2em padding allocated for icon, and 50% height of button
				echo <<<END
				<style>
				body.ie $icon:before, 
				body.ie $icon:after {
					background-size: 1em 50%; 	
				}
				</style>
END;
			}
		}
		
		public function addToFontSymbols($fontSymbols) {
			$fontSymbols[] = $this->id;
			return $fontSymbols;
		}
		
		public function outputIconUpdateJs() { ?>
			<script>
			jQuery(function($){
				<?php if (!function_exists('et_fb_enabled') || !et_fb_enabled()) { ?>
				db014_update_icon(<?php echo json_encode($this->id); ?>, <?php echo json_encode($this->url); ?>);
				<?php } ?>
				$(document).on('db_vb_custom_icons_updated', function () {
					db014_update_icon(<?php echo json_encode($this->id); ?>, <?php echo json_encode($this->url); ?>);
				});
			});
			</script>
			<?php
		}		
		
		public function outputIconPickerCssFb() {
			if (function_exists('et_fb_enabled') && et_fb_enabled()) {
				$this->outputIconPickerCss();
			}
		}
		
		public function outputIconPickerCss() {
			echo '<style>'.$this->getIconPickerCss().'</style>';
		}
		
		public function getIconPickerCss() {
			$url = esc_html($this->url);
			$id = esc_attr($this->id);
			return <<<END
			.et-fb-option--select-icon li[data-icon="{$id}"]:after,
			.et-pb-option--select_icon li[data-icon="{$id}"]:before,
			.et-pb-option ul.et_font_icon li[data-icon="{$id}"]::before { 
				background: url('{$url}') no-repeat center center; 
				background-size: cover; 
				content: 'a' !important; 
				width: 16px !important; 
				height: 16px !important; 
				color: rgba(0,0,0,0) !important; 
			}
END;
		}		
		
		protected static function getSharedUserJs() {
			return <<<'END'
			function db014_update_icon(icon_id, icon_url) {
				db014_update_icons(jQuery(document), icon_id, icon_url);
				var $app_frame = jQuery("#et-fb-app-frame");
				if ($app_frame) {
					db014_update_icons($app_frame.contents(), icon_id, icon_url);
				}
			}
			
			function db014_update_icons(doc, icon_id, icon_url) { 
				db014_update_custom_icons(doc, icon_id, icon_url);
				db014_update_custom_inline_icons(doc, icon_id, icon_url);
			}
	
			function db014_update_custom_icons(doc, icon_id, icon_url) {
				var $custom_icons = doc.find('.et-pb-icon:contains("'+icon_id+'")');	
				var icon_visible = (icon_url !== '');
				var $icons = $custom_icons.filter(function(){ return jQuery(this).text() == icon_id; }); 
				$icons.addClass('db-custom-icon');
				$icons.html('<img class="dbdb-custom-icon-img" src="'+icon_url+'"/>');
				$icons.toggle(icon_visible); 
			}
			
			function db014_update_custom_inline_icons(doc, icon_id, icon_url) {
				var $custom_inline_icons = doc.find('.et_pb_inline_icon[data-icon="'+icon_id+'"]');
				var icon_visible = (icon_url !== '');
				var $icons_inline = $custom_inline_icons.filter(function(){ return jQuery(this).attr('data-icon') == icon_id; });
				$icons_inline.addClass('db-custom-icon');
				$icons_inline.each(function(){
					if (jQuery(this).children('.db014_custom_hover_icon').length === 0) {
						if (jQuery(this).closest('.et_pb_dmb_breadcrumbs').length === 0) {
							jQuery(this).html('<img class="db014_custom_hover_icon"/>');
						} else {
							jQuery(this).prepend(jQuery('<img class="db014_custom_hover_icon"/>'));
						}
					}
					jQuery(this).children('.db014_custom_hover_icon').attr('src', icon_url);
				});
				$icons_inline.toggle(icon_visible);
			}
END;
		}
		
		protected static function getMutationObserverJs() { 
			return <<<'END'
			db014_watch_for_changes_that_might_update_icons();
			
			function db014_watch_for_changes_that_might_update_icons() {
				var target = document.getElementById('et-fb-app'); 
				var observer = new MutationObserver(function(mutations) {
					mutations.forEach(function(mutation) {
						if (mutation.type === 'characterData') {
							$(document).trigger('db_vb_custom_icons_updated');
						} else if (mutation.type === 'childList') {
							if (db014_may_contain_icons(mutation.target)) {
								$(document).trigger('db_vb_custom_icons_updated');
							}
						} else if (mutation.type === 'attributes') {
							$(document).trigger('db_vb_custom_icons_updated');
						}

					});
				});
				observer.observe(
					document.getElementById('et-fb-app'), 
					{ 
						attributes: true, 
						attributeFilter: ["class"],
						childList: true, 
						characterData: true,
						subtree: true
					}
				);
			}
			
			function db014_may_contain_icons(target) {
				if (target.className === undefined) { 
					return false; 
				}
				var classes = target.className;
				if (classes.search === undefined) { 
					return false; 
				}
				if (classes.search(/(et-pb-icon|et_pb_inline_icon|et-fb-root-ancestor|et_pb_root--vb|et-fb-post-content|et_pb_section|et_pb_row|et_pb_column)/i) !== -1) {
					return true;
				}
				return false;
			}
END;
		}
		
		protected static function getUserCss() { 
			return <<<'END'
			.db-custom-icon img { 
				height: 1em;
			}
END;
		}
	}
}

DBDBCustomIcon::setup();
(new DBDBCustomIcon('myicon', 'http://www.mysite.com/angry-bird-icon.png'))->init();

The final line is the one that actually adds an icon. To add your own icon, give it an id (it doesn't much matter what – I've called mine "myicon"), and change the image url to that of your icon. This calls the class added by the rest of the code, and does all the work of adding the icon to Divi. If you need more icons, just repeat the last line with a different id / URL. 

If you now go into the settings for a module which accepts icons, such as the blurb module you should see something like this:

custom divi icons 2

 

Notice that the final icon is now our custom icon.

Select the new icon and save the blurb module. Now view the page with your blurb module. If all goes well, you should see your new icon, like so:

custom divi icons

Hundreds of new features for Divi
in one easy-to-use plugin

137 Comments

  1. Hi. I'm having an issue where the custom icons in the Blurb module no longer are circled. Built-in icons do show circled but the custom ones don't. I've tried both png and svg custom icons.

    Reply
    • Hey Brian, I’ve just released a fix (v3.2.6) that I think should resolve this. I hope it helps but if not, are you able to share a link to a page showing the issue? Thanks!

      Reply
  2. Hey Patrick, I can't use more than 10 icons. There are more than 10 icons displayed in the booster settings and I can also see and select them in the Blurb module, but they are then not displayed. Instead, all Divi icons are displayed at once. Can you help me? Thank you and greetings Carsten

    Reply
    • Hey Carsten, I just ran a test with 20 custom icons and they display correctly for me. Is there any chance you're able to share a link to an example page showing the problem? There may be something going on that I'm missing. Thanks!

      Reply
  3. Hey, Dan, I am running to an issue implementing the custom icons where the icons appear to be shifted up compared to the base Divi icons. It seems to be the margin-top: -16px on the img tag in the element inspector. Any help would be appreciated.

    Reply
    • Applying the following CSS in the "Divi>Theme Options>General>Custom CSS" appears to have resolve the issue temporarily.

      img.dbdb-custom-icon-img {
      margin-top: 0px;
      }

      Reply
      • Hey Matthew, I'm glad you've found a workaround. I'm not quite sure what was adding that negative margin-top. Is there any chance you're able to share a link to the page you've been working on? I'd love to take a look and see if I can figure out where it came from / how to solve it permanently. Thanks!

        Reply
  4. I tried the php solution but am just getting a group of 6 standard icons together in the blurb icon selector.

    I have used this code in my child theme functions.php file:

    [data-icon="myicon"]::before {
    background: url('https://www.leodisdiamonds.co.uk/wp-content/themes/divi-child/icons/select_stone.svg');
    content:'a' !important;
    width:16px !important;
    height:16px !important;
    color:rgba(0,0,0,0) !important; }

    jQuery('.et-pb-icon').filter(function(){ return jQuery(this).text() == 'myicon'; }).html(");

    Reply
    • The code in the post was lagging a bit behind the code used in Divi Booster which has already been updated to address both the icon picker "6 icons" issue and to add SVG support, so I've updated the post with the code from the latest version of Divi Booster. It's quite a bit longer than the original as it handles more edge cases and does some heavy lifting to keep the visual builder preview updated. But as I say in the post, you can basically ignore all of it but the last line. Hope it helps!

      Reply
  5. Hello,
    I tried the php solution, but this code add a group of 6 icons glued together (6 icons that are in the standard set already).
    Could you help me to use your functions?

    Caroline

    Reply
    • Hi Caroline, probably what you're seeing is the "myicon" placeholder rendered in the standard icon divi font. This means that the javascript code added by the final PHP code is not taking effect correctly. Is there any chance you're able to point me to an example page showing the problem so that I can take a look? Thanks!

      Reply
  6. Hi, I've added svg icon with Divibooster, the icon appears in the module icon list, but when I select it's smaller than other icons (I've added svg icon at 96/96px) and not positionned as wel as other.

    Reply
    • Hi Arno, is there any chance you're able to send me a link to the page you're working on so that I can take a look for you? If that's not possible, perhaps you can send me a screenshot? (Note: if you submit a bug report via the contact form you'll get an auto-response email to which you can attach the screenshot). Thanks!

      Reply
  7. Don't work for SVG.
    Even with SVG safe plugin, i cannot change color… because is a img with Divi booster 🙁

    Reply
    • Hi Funfrock, while you should be able to upload and display SVG icons, you're right – you can't change the color because the icons added via Divi Booster are image files. The built-in Divi icons are added using an icon font, which can be styled in the same way as other text fonts. But images can't be changed in the same way since they contain their own color information, for example, and CSS text colors set on them are ignored. There are some new options for changing image colors using CSS filters, but they are a bit complex (see this StackOverflow answer for example). The easier alternative, if you can use it, is to change the color of the image in an image editor, before uploading it to Divi Booster. I hope to be able to add support for color changing using CSS filters in the future. Thanks!

      Reply
  8. Hi, I was trying to ad the icons but it is show as a gray square , what could be the problem?

    Reply
    • Hey jesus, any chance you're able to send me a link to the page you're working on so that I can take a look for you? Thanks!

      Reply
  9. Hi Dan, I just uploaded a 96X96 icon in the divi booster settings page, shows up in the blurb icon settings in the builder but when I select the new uploaded icon, it does not show up on the builder web page…what am I doing wrong….wp is up to date and divi theme as well.
    I tried changing the icon color and and back ground, circle as well but still can't see it

    Reply
    • Hi Charles, it looks like Divi has made a change which is preventing the icons from displaying in the blurb module preview. The icons should still show up correctly on the site itself (i.e. if you view / preview the page). I've had a look and there doesn't seem to be an easy way to get the icons working in the preview again, so I'll need to spend some more time on that. I'll try and get them working again as soon as I can. I hope it doesn't inconvenience you too much, and like I say, the icons should still display correctly on the site itself. If you find that isn't the case for you, please let me know. Thanks!

      Reply
  10. Hello , i am new to this so im not sure what code i should put for that "We then use CSS to set our small icon as the background for the icon selection button and use some CSS / jQuery to make it display correctly." Can you please help me sir ?

    Reply
    • Hi maucikk, this is actually just describing what the PHP code in the "Adding Custom Blurb Icons Manually" section does. There's nothing else to add – instead, the PHP code adds the CSS and jQuery code for you. I've updated the text to hopefully make this a bit clearer. But let me know if you have any questions, etc. Thanks!

      Reply
  11. Hi – I tried this script to add a whatsapp icon for a button. The new icon appears at the end of the list correctly and has the next sequential number: %%380%%

    The problem I have is that it when I select it as the button icon (left) it just displays a mess of icons over the top of the button text. Any idea what the problem is?

    Reply
    • Hey patrick, the code above gives an example of using the icons with the Blurb module. The Button module uses different HTML and CSS and must be treated differently. I think you should be able to get your button showing just by unhiding that mess of icons (so that you can see it again) and adding this CSS to the site:

      [data-icon="whatsapp-icon"]:before,
      [data-icon="whatsapp-icon"]:after { 
          background: url('http://gochimor.co.za/wp-content/uploads/2019/08/whatsapp-icon-black-invert.svg') !important; 
          content:'' !important; 
          width:1em !important; 
          height:1em !important; 
      }
      

      You might still want to do a bit of tweaking to get the positioning, etc, right (let me know if you need any help), but I think that should at least get the icon showing for you.

      Reply
  12. Can I use SVG icons?

    Reply
    • Hi Dieter, by default WordPress doesn't support SVG icons, so initial attempts to use them to fail. However, you can enable SVG support in WordPress with a plugin such as the free SVG Support plugin (https://wordpress.org/plugins/svg-support/). Once active you should be able to use SVG icons as your custom icons (either with the code above or with Divi Booster). I hope that helps.

      Reply

Submit a Comment

Your email address will not be published. Required fields are marked *