Why is url() needed in CSS when specifiying background-image property? - css

Some insights into the decision would be appreciated. I have a hard time finding the reasons why this is specified in the CSS design.

First of all, all URL/URI resources are notated with url(). Second, how do you want to differ between a standard value like none or inherit and images none/inherit?
For example you could create an image called none, send its MIME type correctly and then use
background-image: none;
What should be used now? The stored file? Or the value called none? Another example are cursor files. You could name your cursor file pointer:
cursor: pointer;
To avoid this ambiguity you use url() to denote URIs/URLs. Then it's absolutely clear what to use and you can name the graphics/resources however you want:
background-image: url(none);
cursor: url(pointer);

I suspect they already foresaw the need to have other background images than URL-based ones. linear-gradient for instance.
Also, since image files do not have to have a file name extension, it would be difficult to distinguish the image file from the other properties in the background shorthand method

Related

How do I add the same CSS property (e.g. background-image) multiple times with React?

I want to do the equivalent of style="background-image: url(foo.jpg); background-image: -webkit-image-set(url(foo_1x.jpg) 1x, url(foo_2x.jpg) 2x)" in a React component.
React requires me to provide a style object, not a string. But a JS object can't have the same property twice.
How do I get two background-image properties? Also, the order is significant – the image-set needs to be last.
It needs to be an inline style. (Because the URL is a dynamic, interpolated value retrieved from DB.)
I think I initially misunderstood your question. Seems you are looking to create a style object to pass as a prop to a component. You can combine your background images into a single comma separated list. You can use a string template to inject the dynamic image urls at runtime.
const style = {
backgroundImage: `url(${url1}),-webkit-image-set(url(${url2}) 1x, url(${url3}) 2x)`,
};
"spassvogel" on GitHub has a clever solution using CSS variables: https://github.com/facebook/react/issues/20757#issuecomment-776191029
The idea is to set CSS variables in the style property, like
style={ "--url1": "url(1.jpg)", "--url2": "url(2.jpg)" }
and then using them from an external style sheet, like
background-image: var(--url1);
and so on.
Turns out this still wasn't enough to solve everything I wanted – this rabbit hole runs ever deeper – but that's no fault of React's, so I'll consider this a valid answer.

CSS Variable loading svg file multiple times

I am using variables in CSS/SCSS. I want to set a background (using an SVG file), but it is re-loading every time I navigate or perform some other action.
My -Variables.scss file:
:root {
--backgroundTheme: url('triangle-dark.svg') no-repeat;
}
$variables: (
--backgroundTheme: var(--backgroundTheme)
);
My styles.scss file:
#import "~assets/_variable";
body:before {
background-size: cover;
background: var(--backgroundTheme);
}
How can I avoid multiple times loading of this file?
PS: This is an Angular 8 project.
I had the same problem recently. It was caused by the inspector - "Disable cache" was enabled:
You just need to uncheck it and it will stop making new requests.
To use the image multiple times in the DOM with only one request from the CSS you should use the content property of your pseudo element target to render the image:
body::before {
content: var(--backgroundTheme, 'alt text');
}
Although you'll probably need another approach in handling the image. It might not work for you.
I have two possible idea, not sure if they works for you but it's an easy check:
If you can, don't use css variables, use scss instead. My general approach is to have a settings.scss file and import it whenever needed in the other files. It's a personal preference, I find it easier to manage like that.
It could as well be something wrong in the backend, are the caching headers set right? You can check that in Chrome itself, by clicking on tringle-dark.svg, Headers tab, then Response Headers.

Referencing paths from a css element to another file

I'd like to be able to put all of my paths in one file ("property file"), so whenever I refernce them , the provided functionality should imiplement:
some_file.css
#facebook_link {
background:url(../refereced_file/$facebook_link_url); // ?
background-repeat:no-repeat;
width: 12px;;
height: 23px;
}
refereced_file
$facebook_link_url : ../images/old/facebook.png
I'm aware, as a server-side developer (mostly), that the mechanism of the processing of the browser is different from a compiler, and yet, I want to be able to achieve the property file functionality ( "propObject.getProperty(key)").
I'm not using Saas or SCSS, nor CSS variables.
Thought of making another CSS file with an element and referencing to it, but have no idea how to.
I think the only way is either to use SAAS/SCSS or parsing the css file on your server and look for any variables which need to be replaced with a value from your property.

Overridden CSS Styles with Background Images

There are two CSS files referenced on the same page: A generic.css file and a custom.css file. The generic file has default styles in it that are overridden by the custom.css file for the same elements. This allows users of the site to customize or "skin" their pages without needing to recreate the entire generic.css file. Only a few styles would be overridden.
My question is the following: If the generic.css file has a style for an element with a background image and that same style is overridden in the custom.css with a different background image, is the first image ever downloaded by the browser?
Also, I want to find out if this is bad practice - customizing or "skinning" a generic CSS file with another custom CSS file to override a few styles, including specifying different background images.
While not totally definitive, this site ran some tests regarding this. The significant statement from that site that is related to your question is:
CSS images are kicked off not in the order in which they appear in the
CSS but in the order in which they’re called in the HTML. I’m not sure
of the precise moment when the download is initiated, but my guess is
that it happens just after the CSS rules have been matched, when the
property values are assigned to the DOM elements.
This at least tentatively confirms what I thought I remembered in the back of my mind reading on this a few years back, namely, that background images which are not ever displayed (as in the generic.css images being overridden by the custom.css images) are not ever downloaded.
Further confirmation of this would be the typical image preloader script that used to be so common prior to sprite images (and is still found in certain uses). It was designed to download images that would be used on :hover in css, because without it, the image would not load until the first hover was initiated, and this caused an unsightly delay. So that, also, argues for the fact that unless actually displayed (or preloaded), the background images themselves are never loaded.
I don't think there are generally any issues with "skinning," unless you are essentially overwriting most or all of the generic.css with custom.css, then one could argue, why load the generic at all. But as you said, normally there are just a few styles overwritten.
I think i answered NO and NO BAD PRACTICE. Because when the css file readable / executable by the browser, the browser will make comparisons to find the same value or the difference between css file and then combine them.
Easy example:
css1.css on file there is a line:
.test {display: block; width: 100%; height: 600px; background: #991100 url("image1.jpg") center top; border: 1px solid red;}
then the css2.css there is also the line:
.test {background: #991100 url("image2.jpg") no-repeat center center;}
the result of a combination that will be executed and run by the browser are:
.test {display: block; width: 100%; height: 600px; background: url("image2.jpg") no-repeat center center # 991100; border: 1px solid red}
where the "background: # 991100 url("image1.jpg") center top;" read but not called / executed by the browser.
Far as I know the value of the file css1.css be stacked by the value of the css2.css. What if there a css3.css file? then the file css3.css will also stacking on the combination of css1.css and css2.css.
Hope it helps.

a[type="application/pdf"] vs a[href$=".pdf"]

What is the difference between these 2 selectors a[type="application/pdf"] and a[href$=".pdf"]
a[type="application/pdf"] {
background-image: url(/images/pdf.gif);
padding-left: 20px;
}
a[href$=".pdf"] {
background-image: url(/images/pdf.gif);
padding-left: 20px;
}
The accepted answer isn't completely correct. No selector does "MIME type matching".
a[type="application/pdf"] will match all links where the "type" attribute is set to "application/pdf". If you want to display a PDF icon you'll need to add type="application/pdf" to all the approprite links.
This is exactly what the type attribute on links is intended for (see the spec), to provide a "hint" to the MIME type. However, the browser doesn't actually know what the type of a file is until it starts downloading it. Just wanted to clear that up.
The other selector, a[href$=".pdf"], matches the URL of the link only. It will match any links that end in .pdf, whether they are actually PDF files or not. And of course, it won't match URLs like file.pdf?v=2.
Your best bet is to mark all links to PDF files manually, either with the type attribute, or since you want IE-compatibility, just a regular class instead.
One does MIME type matching and the other does extension globbing. You should probably use the first one because not everyone uses file extensions.

Resources