4

First of all thanks for reading, and my apologies for my lack of knowledge.

I have a WP site running with a theme and a child theme. I run it in 3 languages Spanish, English and Portuguese; and for handling the translations I'm using WPML plugin.

My problem is that in the translated Portfolios and Contact page the site is not looking quite as I want. After quite a lot of research on WPML support's end the conclusion was that my devs the child-theme including additional CSS sheets that are surprisingly set to post/page specific levels. So the styling goes like in the pictures:

CSSSheetPageLevelStyling

CMorePageSpecificStyling

And the same goes for the Contacts ID posts.

So in this scenario WMPL support solution is to "copy" the script and just change in the copied lines the post id.

I believe this is a short term solution as if in the future any of the following happen I will have to re do it again:

-I want to create a second Portfolio Page -I want to add a new language -For whatever reason I delete the portfolio or contact page and re do it it will have a new post ID

So the question is: Isn't another option to achieve this in a more "clean" fashion? I wouldn't know how but I imagine something like saying in the CSS, for Portfolios the styling should be these -no matter which language-; for Contact, the styling should be these, etc

My dev is saying this approach is wrong, but for me their explanations make no sense.

Any advise would be deeply appreciate

Cheers

  • This is worse than having CSS inline! – Nabil Kadimi Mar 1 '17 at 0:18
2

You're absolutely right in your assumption. CSS should never be tied to post IDs, because they can always change (for example if you decide to migrate your posts to another install).

You can always shift control towards the admin dashboard.

Add a custom field in a post/page that you want styled in a special way (in your example you would have the same custom field in all language versions of the post/page). Let's say it will be wpse_custom_class. Add it to each post/page; the value will be portfolio for this example.

Add this code to functions.php (copied from this answer). When the page loads it will look for a custom field and insert its value as a CSS class on the HTML body element.

function wpse_filter_post_class( $classes ) {
    $my_post_class = get_post_meta($post->ID, "wpse_custom_class");

    if( $my_post_class != '' ) {
        $classes[] = $my_post_class;
    }
    return $classes;
}

add_filter( 'post_class', 'wpse_filter_post_class' );

Your designer can now use it like so:

.portfolio #content .main {
    max-width: 100%;
}

This is more work on the admin side (you or the designer will need to manually go in and specify those CSS classes for all the custom-styled pages), but ultimately it contributes to a very flexible and future-proof solution.

  • 1
    +1'd, I would suggest to use body_class instead of post_class, this will allow to target higher then post level. – Nabil Kadimi Mar 1 '17 at 0:23
0

Why not to use ID specific CSS rules:

Post ID specific CSS can only be a quick fix and it's far from the best practice. Post ID is not reliable in many cases. For example:

  • May be you'll delete a post and replace that with a new post.

  • May be you'll need to migrate your site in the future to another server.

  • May be you are creating a newer version of the post / page and want to review the new post / page before replacing the old one.

In all these cases, post ID is likely to change and those ID specific CSS will not be even applicable any more. So you'll have to update your CSS again to match your design needs. WordPress is extremely customizable, so there is no scenario where you have to use post ID base CSS rules. For a more mature development and design practice, using ID specific CSS rules are highly discouraged. Instead, use one of the options below:

Use Page Templates:

WordPress supports page templates for pages for a long time and from version 4.7 WordPress supports page templates for any post type. So if you you have WordPress 4.7 or later, then you may create specific page template for any posts or pages in your child theme.

This way you don't need any ID specific CSS at all, because once you have those specific templates, whenever you'll need the same design for any page or post, you'll simply have to choose the same template from the post or page editor. That's all. After that, design of that page template will apply to that page, post or custom post type.

Use post_class filter hook:

If you don't want to go to different pages or posts in the admin panel to assign specific templates (may be you have a lot of pages / posts), then you may use the post_class filter hook. This way, you will be able to assign unique CSS classes to different posts and pages that needs them and style them based on those CSS classes. For example, say you have a custom post type movie & you want different CSS class for movie entries. Then in your theme's functions.php file, you may add the following CODE:

add_filter( 'post_class', 'movie_post_class' );
function movie_post_class( $class ) {
    if ( get_post_type() === 'movie' ) {

        // remove these CSS classes from movie entries
        $remove = array( 'css-class-to-remove', 'another-class-to-remove' );
        $class = array_diff( $class, $remove );

        // add these custom CSS classes to movie entries
        $add = array( 'custom-movie', 'my-movie-class' );
        $class = array_merge( $add, $class );
    }
    return $class;
}

Now you can use the following CSS to target movie entires:

.custom-movie {
    background-color: gold;
}

Use body_class filter hook:

In some situations, if you don't want to use page templates and you need more generic control over the entire page design (compared to what post_class will provide), then you may modify <body> class using the body_class filter hook (in the same way that you can do with the post_class filter hook). Like this:

add_filter( 'body_class', 'movie_body_class' );
function movie_body_class( $class ) {
    if ( is_single() && get_post_type() === 'movie' ) {

        // remove these CSS classes from body class
        $remove = array( 'css-class-to-remove', 'another-class-to-remove' );
        $class = array_diff( $class, $remove );

        // add these custom CSS classes to body class of a movie post
        $add = array( 'custom-movie', 'my-movie-class' );
        $class = array_merge( $add, $class );
    }
    return $class;
}

Now you can use the following CSS to target movie custom post page:

body.custom-movie .any-inner-content-class {
    color: blue;
}

Since this custom class is added in the <body>, you can target any element within the page this way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.