How to remove <p> tags from images in WordPress

By default WordPress will wrap any images you insert into a post in a paragraph tag. While this isn’t the worst crime semantically speaking it can make life difficult if you want to style those images a certain way. Typically you can target images within a paragraph tag using CSS however you cannot target the paragraph tag itself.

To get around this limitation here’s a snippet for your functions.php:

// img unautop
function img_unautop($pee) {
    $pee = preg_replace('/<p>\\s*?(<a .*?><img.*?><\\/a>|<img.*?>)?\\s*<\\/p>/s', '<div class="figure">$1</div>', $pee);
    return $pee;
}
add_filter( 'the_content', 'img_unautop', 30 );

In the second argument of preg_replace you edit it to wrap the image in any markup you like, in particular if your theme is HTML5 you would replace <div class="figure">$1</div> with <figure>$1</figure>.

Comments
  • Damon 10 / Mar / 2014 at 8:16 pm

    I’m having similar problems like some resent posters. I have some content that seems to be the perfect storm that renders my content missing, the_content() returns nothing.

    1. An anchor tag surrounded by a paragraph.
    2. An iFrame
    3. A gallery

    Removing one of the above returns my content again.

    Example from my content blob:
    [code]
    Some text.

    example

    Some more.

    The Puppetman from Ema Ryan Yamazaki on Vimeo.

    [gallery link="file" ids="1, 2, 3"]
    [/code]

  • Niklas 14 / Jan / 2014 at 4:38 pm

    Great. Thanks!

  • jerralyn 15 / Jul / 2013 at 8:19 am

    This is wonderful Robert! Thank you for sharing this snippet.

  • Henrique Gusso 15 / May / 2013 at 9:12 pm

    The regex seems to be catching paragraphs that start with a link, even if it’s not an image, puting these text blocks inside as well. Have you noticed that, or am I crazy? Either way, thanks for the snippet.

  • pit 25 / Mar / 2013 at 8:38 pm

    For some reason stops working after a random amount of imgs are adde to the post. And when I preview the draft it suppresses imgs and text altogether.
    I’m using wp 351
    Thanks

    • Robert O'Rourke
      Robert O'Rourke 5 / Apr / 2013 at 11:23 am

      It’s difficult to say without seeing the post and the generated markup. It will really only work for images that are on their own inside a paragraph tag with no other text.

  • John Girdwood 20 / Feb / 2013 at 8:29 pm

    Thank you thank you thank you thank you!!! I needed this especially for a special print.css in my homemade styling and I’m a novice so this really, really helped! The thing, which indents my paragraphs 0.5 inch to look like APA academic format, was bumping my images over, too. This helped so much; thanks again! – jg -

  • [...] Source: Robert O’Rourke [...]

  • Michael 5 / Dec / 2012 at 6:48 am

    Awesome stuff man! Cheers!

  • Oleg 10 / Aug / 2012 at 12:04 pm

    Amazing!!! Thank you very much!

  • Terese 16 / Jun / 2012 at 11:23 am

    Hi! This code works wonders on my blogposts, but nothing at all happens on the static pages. Do you know why? Can I alter it in some way to make it work?

    I’m not used to working with php at all, so I’m sorry if this is a stupid question.

    • Robert O'Rourke
      Robert O'Rourke 18 / Jun / 2012 at 11:09 am

      Hi, the code expects some quite specific markup unfortunately. It might be the way the content has been entered or something to do with the theme. Could you post a link to one the pages with the problem?

  • Amanda 3 / May / 2012 at 1:32 am

    Amazing, thank you so much for sharing this! Worked perfectly.

    • Robert O'Rourke
      Robert O'Rourke 3 / May / 2012 at 10:19 am

      No problem. That’s a lovely looking website you’ve got by the way :)

  • Sikandar Aazam 10 / Apr / 2012 at 11:55 am

    Hi
    I have use this code but not remove p tag please help me

  • David 1 / Mar / 2012 at 7:45 am

    You can also add this to your functions.php, to turn the html editor into a real html editor, removing both “auto P” and “texturize”.

    remove_filter (‘the_content’, ‘wpautop’);
    remove_filter(‘the_content’, ‘wptexturize’);

  • DeN 25 / Feb / 2012 at 4:51 pm

    also you сan use jQuery .unwrap() function
    insert between head tags
    $(“#content p img”).unwrap();

    • Robert O'Rourke
      Robert O'Rourke 27 / Feb / 2012 at 11:25 am

      While that’s true it’s too forceful an approach as you can have small inline images within a paragraph. My solution targets paragraphs that only contain a single image plus I’d rather not rely on javascript just to get my markup right.

      • DeN 27 / Feb / 2012 at 4:44 pm

        In some cases it may be helpful to combine solutions, your perfectly work for WP, but .unwrap() might be useful for other CMS. All depends from situation.
        Any way, thank you for your solution =)

  • Vicky 24 / Feb / 2012 at 6:14 pm

    Please, check the html code.. it leaves a <p> behind.

  • Vicky 24 / Feb / 2012 at 5:46 pm

    After a long research, your script worked smoothly!! Thank you :)

  • Rick Benetti 28 / Jan / 2012 at 10:28 pm

    Hi, your script is a good idea, but have a problem, so many image have a class alignleft, alignright, aligncenter and other. How do I get this class and put at figure?

    • Rick Benetti 28 / Jan / 2012 at 10:56 pm

      I found a solution, if you look here https://gist.github.com/1696087 I’m complete your solution.

      • Robert O'Rourke
        Robert O'Rourke 30 / Jan / 2012 at 12:01 pm

        Thanks Rick, good question and good addition. I’m surprised it works that way using apply_filters() to set a variable. I’ll have to do some more tests on this…

        • Jason 18 / May / 2013 at 3:07 pm

          The above doesn’t actually work, I was wondering if you managed to find a solution to that? I’m struggling.

  • Max 19 / Jan / 2012 at 9:57 am

    Not working for me either, using WP version 3.3.1 ?

    • Robert O'Rourke
      Rob 24 / Jan / 2012 at 10:54 am

      Are you getting any errors? Would it be possible to post the html output somewhere too?

  • Zhen 1 / Nov / 2011 at 7:34 pm

    Thank you so much! This is really an useful script and I used it in my theme :) Thanks a lot!

  • Andrea 8 / Aug / 2011 at 8:57 pm

    Thank you for this. This works perfectly

  • Brent 3 / Jul / 2011 at 3:26 am

    This doesn’t seem to be working for me. Should I be adding something to my pages as well?

    • Robert O'Rourke
      Robert O'Rourke 4 / Jul / 2011 at 10:09 am

      No, it should just go into your functions.php. Can you tell me what version of wordpress and what theme/plugins you’re using?

  • Mel Ich 24 / Jun / 2011 at 2:01 pm

    THANK YOU SO MUCH!!!!!

  • Ray Gulick 18 / Jun / 2011 at 2:32 am

    Thank you, thank you, thank you! Can’t thank you enough for this little snippet.

css.php