tl;dr
What other dynamic solution can be used to set the background-image: url() for a page without using the HTML style="" attribute?
My page starts with 13 elements where I set their url(), when you scroll to the footer our lazy-loader will then load 9 (up to 12) more elements that again have their own unique "dynamic" images set.
I think we'll just have to take a hit to our SEO score, as I don't believe a better solution is available.
NOTE: I can create a JS Fiddle if needed, but I think this is described well/generic enough that it's not needed. Please let me know if this is needed for answering.
Purpose
Our company is trying to improve their site SEO score, one of the items identified for us to fix is to move all HTML style attributes into a single CSS file (or <style></style> declaration). I believe the reason this is being called out as an issue is because we have several elements using this to set their article background-image: url();.
Why not just use <img> tag instead?
Our client has alot of different type of images (dimensions, center of focus, etc) they want to use when publishing an article. In order for us to have the most consistent design regardless of screen size is by using CSS background-image styles instead of an <img> HTML tag. We're also working with some WP/XMLRPC publishing constraints, where we're not able to create a custom solution for this.
So we cannot use HTML for this, if we could this would be an easy fix.
Why this is currently set in the style attribute?
This is the best "dynamic" solution we've found so far. Up until now (with this effecting our SEO score), this has never been an issue. In our CSS styles, we have our .class {} specific background image styles that are shared. The only thing that differs for each article is the image URL, so we set that in the style="background-image: url();" attribute dynamically through PHP.
The problem
My page starts with 13 elements where I set their url(). I "could" have inline CSS at the top where I set dynamic classes for these elements that will have their unique background-image: url();'s, this could work even if it sounds painful to setup/do.
BUT we have lazy-loading happening when you scroll to the footer. We load 9 (up to 12) more elements that again have their own unique "dynamic" images set, all via AJAX. I could do the same thing here, creating another inline <style></style> CSS bit... but here's the kicker. One of our other SEO complaints is for us to combine our multiple inline CSS (as well as JS) into a single declaration. If I keep creating more <style></style> declarations to fix this SEO issue, I'll create/worsen another SEO issue.
The Question
What other dynamic solution can be used to set the background-image: url() for a page without using the HTML style="" attribute?
I think we'll just have to take a hit to our SEO score on this one, as I don't believe a better solution is available.
An idea is to change the background-image inline style with a data attribute that has no effect on the SEO score, then you may add some JS code in order to change them as inline style.
Of course this may have an impact on other script as I don't know excatly how your site is built so you may add this JS code as the first JS code so that all your inline style are changed and you have them ready for any futur script.
$('.box').each(function() {
var url = $(this).data('background');
$(this).css('background-image','url('+url+')');
})
.box {
width:100px;
height:100px;
display:inline-block;
background-size:cover;
border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box" data-background="https://lorempixel.com/400/200/">
</div>
<div class="box" data-background="https://lorempixel.com/300/200/">
</div>
<div class="box" data-background="https://lorempixel.com/400/400/">
</div>
By the way we can generalize this solution to any inline style. So the idea is to have all the style set as a data attribute and then we simply change them to inline style:
$('[data-style]').each(function() {
$(this).attr('style',$(this).data('style'));
/*Not mandatory*/
$(this).removeAttr('data-style');
})
.box {
width:100px;
height:100px;
display:inline-block;
background-size:cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box" data-style="background-image:url(https://lorempixel.com/400/200/);padding:20px;border-color:yellow;">
</div>
<div class="another-box" data-style="background-image:url(https://lorempixel.com/200/200/);margin:20px;border:5px solid pink;height:50px;">
</div>
<div data-style="background-image:url(https://lorempixel.com/200/200/);height:200px;">
</div>
NB: as I commented above, we need to have a balance between the complexity of the site and the score we obtain. If we can easily obtain 80% no need to over complicate the site in order to have 85% or 90% and maybe create some bugs or make the maintenance of webiste site difficult.
Related
I am trying to split my Bootstrap page into three parts - header.php, (page).php, footer.php and I am having trouble with an automatic insertion of a margin-top inline style on load. This isn't in my actual code and I can't find it in the style sheets.
The page looks perfectly fine prior to the split ( http://tinker.help/New_Site/index.html ).
When I split it into components header_th.php ; index.php ; footer_th.php ( http://tinker.help/New_Site/index_splitwrong.html ) the elements all come in and load, but I now have a large white space between the bottom of the index.php content and the beginning of footer_th.php content. If I look at the code in Web Developer tools, there is an inline style being set for the margin-top on the Footer element as follows: footer id="footer" class="dark" style="margin-top: 509.2px;
Clearly, this is coming from something calculated as no-one would set such an odd margin manually and it will disappear if I set the inline style to footer id="footer" class="dark" style="display: inline;" to disable any top or bottom margins (although it hoses all of the other formatting to do that.) I can't override this using footer id="footer" class="dark" style="margin-top: 0px !important;" in my code. Changing it in the Web developer tools fixes it but it is overridden by this automatically generated code and it doesn't stick if I update my code.
I assume I have messed up the divs somehow in the split, although I used the Web developer tools to make sure I was getting all of the code pieces cut from the consolidated index.html page and to ensure I didn't duplicate or miss and open or close div bits in the split pages.
Any advice? I am new to straight Bootstrap HTML5/CSS/PHP programming and have never tried to split the header and footer manually like this.
Thanks in advance.
OK, I somehow messed up my splits. When I started from blank pages, it worked fine. It's also possible that I was loading my js libraries twice as the template loaded them in the head section and I was moving them to the end and may have duplicated them. Thanks all.
If you like to override that margin-top, you can add !important to your CSS value like this:
#footer{
margin-top: 0px !important;
}
But make sure that you add this in your CSS style file or within a new <style> block in that page.
Regarding the automatic margin insertion, probably it's done by one of your Javascript code. Have a look at it!
Here's the fiddle: https://jsfiddle.net/8y6vw1gr/
I have created my own custom navbar. I have kept is separate in a file called main-menu.php
I call it into the header using:
<?php
include "main-menu.php";
?>
The main menu is made up as follows:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<nav>
nav contents...
</nav>
<script>
jQuery Contents
</script>
<style>
CSS Styling
</style>
The problem I am experiencing is that although this is a seperate file, calling into the header... the CSS i have added and the scripts/links called at the top of the page effect the layout/display on all pages of contents below the header.
for example, I am designing an e-commerce store and the description has changed its layout, as a result of the main-menu.php it has become crammed and text which should be bold are no longer bold,.
Is there anything that can be done to prevent the css in main-menu.php from effecting the rest of the page?
Your issues stem from either lack of understanding or misunderstanding of how both CSS and PHP includes work.
The problem I am experiencing is that although this is a seperate
file, calling into the header...
When you import it, though, it is no longer a separate file. The source might be a separate file, but the include function pulls the imported code in, and the interpreters (both PHP and the browser) effectively see them as a single file. Since the final HTML/CSS/JS code is output into a single file, it follows all single file rules.
the CSS i have added and the
scripts/links called at the top of the page effect the layout/display
on all pages of contents below the header.
Yep, that's what happens when you add CSS to a page. This is part of the cascading part of Cascading Style Sheets (CSS).
The ideal way of addressing this is to better understand how the cascade works, but for now, we'll just address the problem in one of the easier ways and you can go from there as you learn.
Odds are good you have something like this in your styles:
a {
font-weight: bold;
}
That's going to make all of your links bold. All. Of. Them. This is because the browser is only matching a tags.
So, to make all of your <nav> links bold, you would do this:
nav a {
font-weight: bold;
}
If you have more than one <nav> element on your page, you can add classes and/or identifiers to them in order to tell them apart. The recommended way is to use classes for CSS, but when used sparingly and mindfully, I find IDs to be particularly helpful.
So, you might do something like this (IDs):
#header-nav a {
font-weight: bold;
}
Or this (classes):
nav.header a {
font-weight: bold;
}
What all of these do is tell the browser to only style links that are within <nav> elements (or, more specifically, nav elements classed header or the element named "header-nav").
What About The Bootstrap Styles I Don't Want?
This is where Bootstrap's class-happy nature works in your favor. Just don't use Bootstrap's classes, and you won't get most of its styles.
From there, you just weed out the styles still applying to your element, and override them. This can be a little hairy with these libraries, but such is the nature of the beast.
So, if you have a style like from Bootstrap:
.nav.header a {
font-weight: bold;
}
You would simply match the specificity, or get a little more specific if necessary:
.nav.header a {
font-weight: normal;
}
/* Or... */
.my-nav.nav.header a {
font-weight: normal;
}
You can find out what selectors Bootstrap is using by opening your browser's developer tools and inspecting the affected items. If you're unsure, you can use the developer tools to turn on and off applied styles, or add your own. Then, once you find the selections, you can match them in your stylesheet to override Bootstrap and set it back to the original value.
So How Does Vue Do It?
As a bit of a bonus, I'm adding this in. You may see or have seen libraries such as Vue or React that allow for the creation of components. These are fully-encapsulated UI items, that maintain their own HTML, CSS, and JS, and don't interfere with one another. It may be how you came up with the way you're trying to do it.
However, what these libraries do under the hood is, at compile time they "namespace" everything, similar to what I explained, above. Your <foo> component becomes <div class="foo"> and your a { font-weight: bold; } becomes foo a { font-weight: bold; }. Similar technique, just automated.
There are a couple of ways of doing this.
1. Using different selectors
If your <div>s are all being affected by bootstrap and you don't want that, then simply assign an id or class that is not being used by bootstrap and then this will not conflict with bootstrap's style.
A common class name used by bootstrap in some divs is the alert class. So if you have a div with a class alert, but you want it to look different than bootstrap's style, then consider it giving it another class name such as alert-custom to keep both styles applied to your elements (depending on what class is being applied to the element)
2. Overriding Style
You could override whatever style you have already loaded for a particular element by making the desired CSS declaration the bottom-most declaration for that particular element.
If you have some CSS rules for a <div> element in your bootstrap <link />, but then you declare some other rule in a <style> element somewhere else (anywhere is fine, as long as it is BELOW the style you want to override) for that particular element or tag, then that declaration will supersede the bootstrap styling.
3. In-line Styling
This will override any previous styles declared for a particular element. You can read more about it here
I hope this helps!
you can add the !important property to the item you want to modify, this property will overwrite the current one. For example:
<div class="your-class">Text modiefed</div>
<!-- new css -->
<style>
.your-class{
font-weight: bold!important;
}
</style>
Im quite new to using Redux Framework for creating a Wordpress options panel.
I have created a option to change the width of a logo img.
But i dont know what would be the best way or practice of the following:
Just target the css and output the width.
.logo img {width:/* css output */;}
Use php to call the option.
global $redux;
<div class="logo">
<img width="<?php echo $redux['logo-dimensions']['width'];" />
</div>
I would like to think number 1 is the best.
But what would be the best practice of these, and/or is there a better way than this? Pros/cons?
I would like to understand abit deeper why or why not.
Would appriciate a good answer :)
In case with <img>, it is allowed (by HTML5 standards) to use inline width and height attributes, which would probably be more effective for page rendering, considering your css is an external file.
However, if you include some of your inline css to prevent content rendering block and the logo image width is declared, the CSS solution would be equally effective.
I think the below given code will be more efficient for css image output:
.logo img {
background-image:url("/imgPath");
background-size: 80px 60px;
background-repeat: no-repeat;
}
Hey lets say i got two links on my page and i have some sub links(show up when main link clicked). Those two links have different background image.
*link1
-link1underlinkone
-link1underlinktwo
*link2
-link2underlinkone
-link2underlinktwo
-link2underlinkthree
I can easily change background image on those two main links, but how should i pass same background style to my under-links? And underunder-links if i would have any?
edit: woops forgot to tell i want change background image of BODY not the link/links ;)
You should try putting both the main links in seperate div's with their sub-links. Set the background on the div (set display to none so it is invisible), and then set the background on all the links to inherit, so they take the background from their parent div.
Edit: Use the code I made below
<head>
<style type="text/css">
#link1wrapper {
background-image: url(background1.jpg);
visiblity:hidden;
}
#link2wrapper {
background-image: url(background2.jpg);
visiblity:hidden;
}
.linkmenu a{
background-image: inherit;
visibility: visible;
}
</style>
</head>
<body>
<div id="link1wrapper" class="linkmenu">
*link1
-link1underlinkone
-link1underlinktwo
</div>
<div id="link2wrapper" class="linkmenu">
*link2
-link2underlinkone
-link2underlinktwo
-link2underlinkthree
</div>
</body>
Edit: I fixed the code. Now, it puts a background on the div's and hides the div's, then I set the links in the div's to visible and voila, all the links have inherited it's background. The things you should be aware of are not to put anything else in the div's. If you do, you have to style them to set them to visible and set their background to none.
That's all I could come up with based on the very limited information you have given me. You didn't use any code, any examples, or any references, so it's very hard to answer your question accurately.
I better get an upvote for this one =p
Guessing you want to make a proper menu structure here is a little demo I made.
http://jsfiddle.net/sg3s/fPu9S/
The two key properties used are background-image: inherit and visibility: hidden.
background-image: inherit will make the element inherit properties from its direct parent, if no image is specified this means no properties will be inherited. Due to this we need to make the ul for the sublinks / menu inherit the properties from its parent too... Then we mask this image on the ul using visibility: hidden and since visibility default setting is inherit we need to make the lis visible again with visibility:visible.
So thats the explanation of what is actually going on. inheriting the styles can't be used together with the anchor tags unless you nest the sub links inside the main anchors and I don't think that is even valid or accepted code.
How to make an external PHP widget page have its own CSS.
The catch is - when the external page is included it's been affected by the stylesheet of the host page.
The included page is actually a comments 'widget' (with his own .css file, about 30 lines, not much) and the height and width flexibility are a MUST HAVE.
The PHP include was so far the best solution, but I lost my hair adjusting its CSS file to fit / null (adding/excluding/ styles) any possible host web page.
Example:
if the host page has styles for img borders I have to null them from the widget's style.css, same for H3, P, and so on.
How would you preserve a widget stylesheet from being affected by the host page styles, beside using iframe?
You know CSS is a client-side thing; it doesn't know about PHP and how the page has generated on the server.
You have got to focus on the final resulting HTML and redefine tags and classes and IDs so that your desired style rules apply to right elements.
You can limit the scope of CSS rules by surrounding that part in a div with a unique ID or class and use it in your CSS selectors so they wouldn't apply to elements outside of that div.
Or if you can't do that you have to use stronger rules to override included ones for your other elements. Which will be a little messy, but you can override styles applied to an element using several techniques like !important or having more selector parts.
For example, in both of the below samples, the second rule will overwrite the first one:
#comments .link { color: red; } /* Included page rule */
#header .link { color: blue !important; }
or
#comments .link { color: red; } /* Included page rule */
#header div a.link { color: blue; }
You might want to apply a mini CSS reset on your included code. Surround your code in a unique id, like so:
<div id="widget">
<!--your code here-->
</div>
Now apply the reset to everything inside this, using a basic CSS reset like Eric Meyer's, available here: http://meyerweb.com/eric/tools/css/reset/
Now, apply your own CSS. Nearly all outside CSS will be wiped out, and yours will be applied.
Try surrounding your widget code in a div with an id. Then prefix each CSS selector used in the widget with that selector.
ex.
<div id="widget"><p class="nav">hello</p></div>
instead of,
.nav{
// styles
}
do
#widget.nav{
// styles
}
CSS Styles prioritize like this:
Browser default
External style sheet
Internal style sheet (in the head section)
Inline style (inside an HTML element)
Depending on how much CSS you need to apply, you could writ it on the "head" tag.
Hope the suggestion helps.
If I understood correctly, your included page has some CSS rules such as:
div {/*rules*/};
p {/*rules*/};
and so on.
You should change your CSS selectors from the most general ones (div selects all the divs in the page) to the most particular ones (use them in this order: id, class, child-selector) in order for your rules to apply only to your included elements.
For example, say your included page is wrapped in a div, the PHP code would be:
<div id="my_page">
<?php include "myPage.php"; ?>
</div>
Then, all your rules for the page should refer only to the children of the element with the id my_page:
Instead of
div {/*rules*/};
you'll have
#my_page div {/*rules*/};