CSS :after, content: having two values? - css

I've got CSS on my links depending what type of link it is. In this case it's password protected, and external link.
So I've got CSS like this:
a.external-link:after { padding-left: 2px; content: url(../images/icon-external-link.gif); }
a.restricted-link:after { padding-left: 2px; content: url(../images/icon-lock.png);}
However when I try something like this:
<a class="external-link restricted-link" href="some link">Some Link</a>
It only displays the last icon, in this case the icon-lock.png. Which makes sense, since the content value can only be set once not combined, so the last class declaration is overwriting it. Is there anyway to combine these two so I can mix and match these link classes easily (I've got 4 total). I don't want to make separate classes/images for each combo.

Hate to break it to you, but you're going to have to make separate classes/images for each combo. Especially as there would be no way of knowing which content should go first.
a.external-link.restricted-link:after
{
content: url(ext) url(res);
}
vs
a.external-link.restricted-link:after
{
content: url(res) url(ext);
}

Related

How to think about styling AngularJS components?

I'm working on an AngularJS project with the aim of slowly getting things in order for Angular 6, or whatever version is out when we start on the upgrade. One of the big pieces of that work is converting existing directives into components.
The thing I'm struggling the most with, is that every instance of a component introduces an extra element into the DOM that wraps my actual component HTML and breaks the hierarchy, making it very hard to write CSS that does what it needs to.
To illustrate my dilemma, imagine a simple component called alert that provides styling for various types of messages you want a user to pay attention to. It accepts two bindings, a message and a type. Depending on the type we will add some special styling, and maybe display a different icon. All of the display logic should be encapsulated within the component, so the person using it just has to make sure they are passing the data correctly and it will work.
<alert message="someCtrl.someVal" type="someCtrl.someVal"></alert>
Option A: put styling on a <div> inside the extra element
Component template
<div
class="alert"
ng-class="{'alert--success': alert.type === 'success', 'alert--error': alert.type === 'error'}">
<div class="alert__message">{{alert.message}}</div>
<a class="alert__close" ng-click="alert.close()">
</div>
Sass
.alert {
& + & {
margin-top: 1rem; // this will be ignored
}
&--success {
background-color: green; // this will work
}
&--error {
background-color: red; // this will work
}
}
This works fine as long as the component is completely ignorant of everything around it, but the second you want to put it inside a flex-parent, or use a selector like "+", it breaks.
Option B: try to style the extra element directly
Component template
<div class="alert__message">{{alert.message}}</div>
<a class="alert__close" ng-click="alert.close()">
Sass
alert {
& + & {
margin-top: 1rem; // this will work now
}
.alert--success {
background-color: green; // nowhere to put this
}
.alert--error {
background-color: red; // nowhere to put this
}
}
Now I have the opposite problem, because I have nowhere to attach my modifier classes for the success and error states.
Am I missing something here? What's the best way to handle the presence of this additional element which sits above the scope of the component itself?
I personally do option A. This allows you to easily identify and create specific styles for your components without fear that they will overwrite site-wide styles. For instance, I'll use nested styles to accomplish this:
#componentContainer {
input[type=text] {
background-color: red;
}
}
This will allow you to make generic styles for your component that won't spill out into the rest of your solution.

Exclude CSS class from inheriting

I have tried to search but am not sure if I am posing the question right.
I applied the following css to my site:
a[target='_blank']::after {
content: '\29C9';
}
This means that all external links will get the icon attached to it. So far, so good, it works as expected.
There are some situations though where I do not want this to happen, like in social share buttons. How can I exclude some classes?
Like when the link appears in a div with class 'socialbutton'?
PS I cannot add other style to these buttons (WordPress website and generated code)
You can overwrite this css code by adding new css to the class.
Example you can overcome this:
a[target='_blank']::after {
content: '\29C9';
}
By doing this:
.socialbutton::after {
content: '\fff' !important;
}
You can use the :not() selector:
a[target='_blank']:not(.social)::after {
content: '\29C9';
}

CSS Selector doesn't work as expected

I am developing a website which relies on user input to create scripts
As a defense in depth solution I am adding a blacklist protection to omit all links with an external source. I tried the following code snippet but it doesn't work (my browser supports it because w3schools sample works on it) :
[href~=//]
{
display: none;
}
There's a subtle different in the selectors that you are using :
[attribute~="value"] - This checks for a specific word (i.e. wrapped in white-space or the exact string)
[attribute*="value"] - This checks if a given set of text is contained at all.
You'll see that the second approach works, whereas the first does not.
Additionally, you'll want to ensure that you have the specific element you are targeting and that you are wrapping your value within quotes, as seen below :
a[href*='//']{
display: none;
}
Example
a[href*='//'] {
display: none;
}
/* Added to demonstrate selector differences */
a[href~='//'] {
color: green;
display: block;
}
<h4>[href*="value"] Examples</h4>
<a href='http://www.google.com'>Hidden</a>
<a href='stackoverflow.com'>Shown</a>
<a href='Check // this out'>Green</a>
<h4>[href~="value"] Examples</h4>
<a href='a//'>Hidden (since not whole "word")</a>
<a href='//'>Shown (as exact)</a>
<a href='//a'>Hidden (since not whole "word")</a>
Try this:
a[href*="//"]{
display:none;
}
Select all a objects whose href contains '//'
working fiddle

What effect does \f have when applied to css?

I am reading the code from Font-Awesome, which is a library that (from what I understand) overwrites parts of Bootstrap to modify some of the code.
There is a class called fa-twitter, created in Font-Awesome:
.fa-twitter:before {
content: "\f099";
}
I do not understand what \f is doing in this situation, and where the numbers "099" are being used. I have tried searching Font-Awesome on Github, thinking perhaps .fa-twitter is defined elsewhere, or something the numbers could be used in, but I haven't found anything so far.
It's not \f that matters. It's Unicode character code.
\f099 means It's not literal "f099" but Unicode value of "f099"
Table itself
Example:
#first:after {
content: "\0178"
}
#second:after {
content: "0178"
}
With "\": <i id="first"></i>
<br/>Without "\": <i id="second"></i>
It's not 'f', it's the content that's important:
If you have code like this:
<p class="email">myemail#gmail.com</p>
You'll just get the email address: myemail#gmail.com.
But if you add this in the CSS:
.email:before {
content: "Email: "
}
You'll get Email: myemail#gmail.com without making any changes to the HTML.
In this case, it's adding a symbol, indicated by the code F099. In other words, the twitter bird:

Remove words from link using a:visited once a link has been clicked

is there a way with pure css to Have a link that might say "New! Watch Video" and then once someone has clicked the link have it remove the "New" portion of the link. I'm assuming this can be done w/ Jquery but I'd like to see if there is an way to remove it with just css.
Rather than removing words, add the word "New" if the link hasn't been visited yet
a:before {
content: "New! ";
}
a:visited:before {
content: "";
}
No extra markup, and you don't need to put the word "New" everywhere.
Wrap the "New!" in a span inside the anchor:
<a class="newText" href="somepage.html"><span>New! </span>Watch video</a>
and in your CSS, set:
a.newText:visited span { display: none; }
I would recommend using a class on the anchor (like "newText" above) so that this formatting will only be applied to the links you want it on. And keep in mind that the "New!" text will reappear if the user clears their browser history.
Assuming the anchor will take you to a new page you can use the following technique:
a:before {
content: "New! ";
}
On any page you wish to remove or change it, you can add a body class
body.blah a:before {
content: "";
}

Resources