Adding Custom Icons to Divi

|

Divi 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 in-built way to add new fonts. Fortunately, there is a way we can work around this to add our own custom icons.

Note: this post is about uploading your own icons for use in modules that support the Divi icon picker. See here if you instead want more icons in the Social Media Follow Module.

Adding Custom Icons using Divi Booster

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
  2. Open the 'Site-wide Settings' toggle
  3. Open the 'Icons' sub-toggle
  4. Tick the checkbox next to the 'Add custom icons for use in modules' option to enable the feature.
  5. Click on 'Choose Image' to select the icon you want from the media library (or upload a new one), then click 'Use Image'.

The option should now look something like this:

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. To get rid of an icon, click on the little 'X' next to the icon you would like to remove.

Save the Divi Booster settings and your icon will now be available to you in the modules icon list.

Note: to use SVGs, add SVG support to WordPress with a plugin such as SVG Support.

Styling the Custom Icons

It'll depend slightly on which module the icons are being used in, but in general the size can be set in the same way as the rest of the icons. Similarly, the background should work as long as your icon image has a transparent background itself. Changing the icon color is a different matter. The built-in icons are 'font icons', meaning they are basically text, while the icons added in that Divi Booster option will be images. This means that the settings for changing the color of the built-in icons won't work on the added image icons. I hope to be able to add something in the future (probably along the lines of the filter options Divi includes for the entire module area). I'll update here if / when I'm able to. In the meantime, the best I can suggest is to modify the colors of your icons in an image editing program prior to uploading.

Compatibility with Third-Party Modules

In addition to working with the built-in Divi modules, this feature will work with many third-party Divi modules. While it will usually work without modification, some plugins will need a bit of extra work to ensure they are compatible. If you encounter a case where the custom icons aren't working on a particular module / field, please let me. Some plugins where I have explicitly tested for and resolved compatibility issues, along with the version they were addressed in Divi Booster, are:

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

Important: the PHP code given here doesn't work in Divi 4.13 upwards. Divi Booster has already been updated to be compatible with the latest version of Divi. I hope to be able to update the manual code with the relevant fixes here soon.

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

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

Divi Booster

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

160 Comments

  1. Hi,

    just thought i'd say that I made this work by doing the manual install, but I made the icon 46×46, so it fits into the circle if that is selected as an option. If you add your new icon at 96×96, is tries to put a massive circle around everything.

    46x46px makes it the same size as all the other standard icons – I did have to colour it to the correct colour though.

    Seems to work a treat – thanks for posting this fix.

    Reply
    • Hey Jon, thanks for letting me know how you got on. It's useful to know that 46×46 works well with the circle – I don't normally use it with the circle and wasn't aware of that. Cheers!

      Reply
    • Hi Marie, are you able to share a link to the page so that I can take a look?

      Reply
  2. For the life of me, I just can't get it to work. :(

    Tried all sorts of things.

    Reply
    • Hi Sidian, it looks like it's a caching issue. Something (probably a performance plugin) is stopping Divi Booster from updating its JavaScript when you change the icon settings, which means the code to display the icon correctly isn't being shown.

      I've written a post on how to fix caching issues.

      Also, recent version of Divi Booster are able to deal with the caching so if you upgrade Divi Booster to the latest version, I think that should also fix it.

      Reply
  3. Oh ok, I think I got it. This allows graphic icons to be added to the Blurb module? So, is there no way to add font icons into Divi that show up in the Blurb Module and can be manipulated with color etc? i.e. same type of icons that are already in the Divi Blurb Module?

    Thanks much!

    Reply
    • Hey Bob, yes that's correct – this code is for graphic icons. It should be possible to add font icons, but it's not something I've been able to explore fully yet. If / when I do I'll post an update here.

      Reply
  4. Dan, love the plugin!

    Adding new blurb icons, added as 96×96 png, but when I select to place "left" the icon display size is way smaller than when I use the standard divi icons.
    http://sharreid.com/test/

    Any ideas?

    Cheers, Reid

    Reply
    • Hey Reid, it's actually a Divi default that the "left" icons are smaller than the "top" positioned ones. If you'd like to make the left icons bigger, I've just added an option to Divi Booster to do so, and put up a post describing how it's done:

      http://divibooster.com/make-left-placed-divi-blurb-icons-larger/

      Reply
  5. Just getting into WP & Divi, and purchased Divi Booster.

    I am trying to install three custom icons (I have .png and .svg files).

    I made the .png files 96 x 96, and uploaded them through the Divi Booster widget. They appear as images in the media library and not blurb icons. Certainly I'm not clear as to what the proper procedure is and could use some help.

    Thanks!

    Robert

    Reply
    • Hey Robert, the feature uses the media library to handle the icon upload and storage. If you go into the settings for one of your blurbs you should see the same icons available for selection as the blurb icon. They'll appear just after the built in icons. Let me know if this isn't the case.

      Reply
      • They aren't in the icon list, but are in my media library.

        Reply
      • Dan-

        I figured it out. I cpoied the image link into the booster "upload icon" area, and it worked!

        What kind of file should I upload to toggle the color (dark/light) of the icon?

        Reply
        • Ah, I see what's happening. When you upload an icon, the media library gives you two options "Save all Changes" and "Insert into Post". It's not at all intuitive, but you should click "Insert into Post" and it'll automatically place the URL into the "upload icon" area. I'm planning on replacing this system with something more intuitive and seamless, which would also be able to handle the upload of multiple icons. Anyway, glad you got it working!

          Currently it isn't possible to control the darkness / lightness of the uploaded icon (as it is an image file rather the an icon font as Divi uses). I'll look into changing this in the future.

          Reply
  6. Hello – about 1 month into WordPress themes – have the DIVI – I'm confused when you say "add the image URL" – I only have the images on my computer… how do I get an image URL?

    Thanks
    Angie

    Reply
  7. Hi,

    I am in the initial developing stage of creating my website. I have several icons that are in color, and I would like to change them to grey.

    Does anyone have an easy fix?

    Reply
  8. Hi Dan, I keep getting a fatal error when I do this…any idea what my mistake is?

    Fatal error: Cannot redeclare myfont_icons() (previously declared in /home/brennanwesterman/public_html/wp-content/themes/Divi/functions.php:4618) in /home/brennanwesterman/public_html/wp-content/themes/Divi/functions.php on line 4627

    Thanks!

    Reply
    • Oops, sorry Brennan. It looks like I copied the same function twice. I've updated the code, so hopefully it'll work for you now.

      Reply
      • Dan,

        I get the same error message as Brennan. "Fatal error: Cannot redeclare myfont_icons() (previously declared in /nas/wp/www/staging/kavi/wp-content/themes/Divi/functions.php:4801) in /nas/wp/www/staging/kavi/wp-content/themes/Divi/functions.php on line 4824"

        Any idea why I might be getting this. I added multiple icons at the same time. Instead of naming them as "myicon" I named them each differently and made sure the names matched between both functions. Any advice is greatly appreciated.

        Reply
        • Hi Jay, the problem in your case is that your repeating the function declarations. PHP doesn't allow two functions to have the same name. To fix this, you could add a number to the end of each function name, so your code would end up looking a bit like this:

          /* First icon */
          function myfont_icons1($icons) {
              ...
          }
          add_filter('et_pb_font_icon_symbols', 'myfont_icons1');
          
          function my_custom_fonts1() { 
              ...
          }
          add_action('admin_head', 'my_custom_fonts1');
          
          /* Second icon */
          function myfont_icons2($icons) {
              ...
          }
          add_filter('et_pb_font_icon_symbols', 'myfont_icons2');
          
          function my_custom_fonts2() { 
              ...
          }
          add_action('admin_head', 'my_custom_fonts2');
          

          Hope that makes sense!
          Dan

          Reply
  9. Hi, just a quick note to say thanks for all your Divi articles and for the effort and time to write them. The plugin you are writing sounds like a great idea and I look forward to its completion.

    Reply
    • Thanks Antony! I'm glad you've found them useful, and I too look forward to the completion of the plugin ;) I'm hoping to have it ready within the next week or so.

      Reply
  10. Hi dan, it`s nice to hear You work on so cool stuff. So at the moment I`m wondering, whether to focus rather on adding more text colours to the main theme UI. Like more than light and dark.

    When it comes to icons i`d create new custom post type hidden in menu (or not) manageable on plugin options page, with three fields; title (name of icon) and two-sizes of images to add from media library.
    Then I`d just use Your script to iterate over posts in every place needed, extracting values.

    But what also concerns me – i`d so like to maintain functionality of webfonts – scalability and changing colours. Thats hard to achieve with png. Some time ago I did a project using SVG php files with parameter for fill colour, like: "my-image.php?f=AABBCC". It would be possible, but still, every image should be prepared for adding parameter.

    Ooohh.. whatever, i`ve got so much to do that i don`t even know why am i still wondering about this :-)

    Reply
    • Ha ha, sounds like we're the same – keep getting distracted by the fun stuff :)

      I haven't tried myself, but it should definitely be possible to add support for other webfonts. I guess there are two options – one, you could replace the ET font with your own via CSS. But that limits you to one font and the characters chosen by ET. Another option would be to register an icon for each character in your new font, and style each one via CSS (setting the content to the character code). It should be a (fairly) simple modification of the PNG code in this post.

      I'd love to see more text color options than just light and dark – it does seem a bit too few!

      Reply
  11. Thank You so much!
    I am thinking of developing simple plugin allowing management of blurp icons

    Reply
    • No problem, entio!

      There's definitely a need for a plugin to allow management of the icons.

      I've actually got a plugin in the pipeline which implements many of the tips I've written about on this site. One of the things I've already implemented is the ability to add new blurb icons. I'm hoping to release it in about two weeks, so if you're just after a convenient way to manage the blurb icons on your site it will save you the effort of writing the plugin yourself.

      If you're planning to write the plugin for other reasons (fun, money, etc) please do come back and share a link here when it's ready. I'll also be happy to test it out for you, if you like.

      Reply

Submit a Comment

Comments are manually moderated and approved at the time they are answered. A preview is shown while pending but may disappear if your are cookies cleared - don't worry though, the comment is still in the queue.

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