Recently when I started to use my own implementation of methodology based on BEM I stuck on modifiers for nested elements.
I want to change link color to red when product-desc-name has class mark.
The following example presents the problem.
What should I do to keep the final style the same but without duplicating class names?
.product-desc {
&-name {
&.mark {
/* this section is ugly */
.product-desc-link {
color: red;
}
}
}
}
<ul class="product-desc">
<li class="product-desc-name">
<a class="product-desc-link">Param1</a>
</li>
<li class="product-desc-name mark"> <!--add class .mark-->
<a class="product-desc-link">Param1</a>
</li>
</ul>
This is a typical weakness of BEM. I have search for long, but do not seen any good solution for this so I make my own.
At first I would change the class name. Because UL element should be call 'product-desc-list'. The LI element 'product-desc', as this is in fact exactly a product description for a product.
The more important is the condition of the product. Therefore the selection of the element should be mentioned first. This allows several blocks to be used for one component.
The first is the component definition. The next define possible states like selected, in progress etc.
Here is an example for illustration
// your product in default definition.
.product-desc {
&--link {
text-decoration: underline;
}
}
// your product in mark state definition
.mark {
.product-description {
&.--link{
font-weight: bold;
}
}
}
<ul class="product-desc-list">
<li class="product-desc">
<a class="product-desc--link">Param1</a>
</li>
<li class="product-desc mark"> <!--add class .mark-->
<a class="product-desc--link">Param1</a>
</li>
</ul>
Related
I am trying to alter MediaWiki's hideous default color for visited links and keep the red color for new links. New links have class new or their parents have this class set. So I tried
:not(.new) a:not(.new) { color: #0074D9 !important; }
But as I inspected in the browser console, this rule overwrites li.new a - which it should not. Experimenting a bit,
li:not(.new) a:not(.new) keeps the red color for li.new a,
*:not(.new) a:not(.new) overwrites the red color
Can you explain this behavior and recommend a CSS rule forcing blue color for all links but the new ones?
:not(.new) will match every element that does not have a new class. So for example :not(.new) a in <li class="new"><span><a>...</a></span></li> will match span a. In general, :not() is rather hazardous to use without an accompanying specific class or id that you know won't be used elsewhere.
What you want is "a tags which do not have a .new ancestor" (as opposed to "a tags which have a non-.new ancestor"), which cannot be expressed as a CSS selector. Given you know that the .new element is the grandparent, you might be able to write something like :not(.new) > * > a instead.
set a color for li.new a and li a.new and then set a color for li:not(.new) a and li a:not(.new) .
If you want just the visited links to change color add :visited to the css selectors
ul li.new a, ul li a.new {
color:red
}
li:not(.new) a {
color:green
}
a:not(.new) {
color:green
}
<ul>
<li>
<a href="#" >Normal Link</a>
</li>
<li class='new'>
this will NOT be green because LI has class new
</li>
<li>
<a href="#" class='new'>this will NOT be green because it has class new</a>
</li>
<li>
<a href="#" >Normal Link</a>
</li>
</ul>
Is it possible to set a custom style for an individual marker?
I'm trying to set the border color to a custom one for each marker I add, instead of using one single class. Those colors are ones I can't know in advance and I need to set them while the program is running. This is why I can't create a dozen classes and use them for this purpose.
You can use dynamic marker similar to what cloud9 uses here https://github.com/c9/core/blob/2d05ddeb7c0c1f6f3b35e305f60d1ba4f39f0294/plugins/c9.ide.collab/author_layer.js#L41 https://github.com/c9/core/blob/2d05ddeb7c0c1f6f3b35e305f60d1ba4f39f0294/plugins/c9.ide.collab/author_layer.js#L98
Here is one way you can do that: https://jsfiddle.net/sheriffderek/wkwzprfh/
markup
<ul class="marker-type-list">
<li class='marker-type'>
<button class='js-create-marker' data-color='red'>Create red marker</button>
</li>
<li class='marker-type'>
<button class='js-create-marker' data-color='green'>Create green marker</button>
</li>
<li class='marker-type'>
<button class='js-create-marker' data-color='blue'>Create blue marker</button>
</li>
</ul>
<ul class='marker-list'><!-- X --></ul>
script
$('.js-create-marker').on('click', function() {
var color = $(this).data('color');
console.log(color);
$('.marker-list').append('<li class="marker ' + color + '">marker</li>');
});
styles
.marker.red {
color: red;
}
.marker.green {
color: green;
}
.marker.blue {
color: blue;
}
Is it possible to use wildcard to select data attribute by name with CSS only?
[data-widget-type="*.color"] {
color: orange
}
<ul>
<li>asdasd</li>
<li data-widget-type="red.color">asdasd</li>
<li data-widget-type="none.color">asdasd</li>
</ul>
http://jsfiddle.net/
Yes, it's possible, just not quite the way you've done it. You need to move the delimiter (in your case, the "wildcard" asterisk) outside of your string declaration. There's also a better delimiter for what it looks like you're trying to select. Here's the right attr selector:
li[data-widget-type$="color"] {
color: orange;
}
<ul>
<li>asdasd</li>
<li data-widget-type="red.color">asdasd</li>
<li data-widget-type="none.color">asdasd</li>
</ul>
This will select all the li elements with data-widget-type values that end in color, and change their color to orange.
Here's a JSFiddle demo to play around with it yourself.
[data-widget-type*="color"] {
color: red;
}
<ul>
<li>asdasd</li>
<li data-widget-type="red.color">asdasd</li>
<li data-widget-type="none.color">asdasd</li>
</ul>
More info about Attribute selectors - https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
li[data-widget-type$=".color"] {
color: orange;
}
<ul>
<li>asdasd</li>
<li data-widget-type="red.color">asdasd</li>
<li data-widget-type="none.color">asdasd</li>
</ul>
You can use css selectors for that too.
For specific atribute you can use [] and if you are comparing something in css and want to search at the beginning ^= or if you want to find it at the end $= you can use this.
Also if you don't know where the word is in the comparing word then you can use wildcard * too. So in our case it is li[data-widget-type*=".col"]
As an advice, I like to struct my css files like this.
I always have a css class for colors.
li[class*="red"] {
color: red;
}
So I can also reach it from any other class like any-red, new-red when I don't want to use single red class.
Also don't forget that you can also use li[data-widget-type|="red"] for elements that starting with red. This is an old but good move from CSS2, some browsers may reject it so take care.
So here is the jsFiddle and here is the snippet.
li[data-widget-type$=".color"] {
color: orange;
}
<ul>
<li>asdasd</li>
<li data-widget-type="red.color">asdasd</li>
<li data-widget-type="none.color">asdasd</li>
</ul>
I have an auto generated Wordpress menu that's created the following:
<li class="page_item page-item-23 page_item_has_children">
Main item 1
<ul class="children">
<li class="page_item page-item-52498 current_page_item">
Item 1
</li>
<li class="page_item page-item-52496">
Item 2
</li>
<li class="page_item page-item-52477">
Item 3
</li>
</ul>
</li>
I want to say when I'm on the first sub item, highlight the main li.
This is the CSS I'm using (ideally this would be more simple but due to the nature of the auto generated menu it's a bit messy!):
.page-item-52498.current_page_item li.page-item-23 a {
color:white!important;
font-family:'Museo Sans W01 500'!important;
}
At the moment this doesn't make the first li a white.
That CSS selector doesn't work. You cannot select the .page-item-23 as a child of .page-item-52498, as it is a container for the other in the markup structure.
Have you tried outputting the page ID using the body_class function of WordPress? Then you could try using a selector such as body.page-id-52498 li.page-item-23 a or similar.
The body_class function is used as such (most probably in the header.php template file of WordPress):
<!-- <head> somewhere above -->
<body <?php body_class(); ?>>
<!-- rest of the template somewhere below -->
It should output something similar to this (with a dynamic ID number of course):
<body class="page page-id-112 page-template logged-in admin-bar">
Whenever you've used body_class and it outputs the specific page ID you've declared in the CSS selector I wrote above it will take effect (following standard cascading rules of course).
One for the future - the subject selector should be arriving in CSS4. It's going to be very powerful but easy to abuse I think.
Syntax
!subject > selector {
/* declarations */
}
Example
!ul > li {
border: 1px solid green;
}
Scrolling down to the Parent Selector: http://coding.smashingmagazine.com/2013/01/21/sneak-peek-future-selectors-level-4/
And http://css4-selectors.com/selector/css4/subject-of-selector-with-child-combinator/
I am creating a navigation structure. I tried to use AngularStrap and Bootstrap, but as soon as I injected them into my app, Angular failed. I found this link and constructed my navigation tab-bar. I like how easy it is to customize. My problem is, I don't know how to apply the css for the selected tab in angular. I can't apply an id to an element conditionally, and when I try and break up the css into multiple classes, the tabs don't display the same way.
<ul class="tablist">
<li ng-repeat="tab in tabList" ng-click="setSelected($index);">
{{tab.title}}
</li>
</ul>
vs.
<ul class="tablist">
<li id="selectedTab">Admin</li>
</ul>
What is the best way to apply the selected formatting? See this Fiddle for a more fleshed out example.
Updated: http://jsfiddle.net/dLemh/6/
to have background color change use css important on the class
ng-class="{selected: isSelected(tab)}"
$scope.currentSelectedTab = {};
$scope.setSelectedTab = function(tab){
$scope.currentSelectedTab = tab
}
$scope.isSelected = function(tab){
if(tab == $scope.currentSelectedTab){
return true;
}
return false;
}
Please let me know if anything
I found this SO Post that I was able to use and fix the CSS formatting with regards to their priority.
.tablist li.selectedTab a {
background: none;
border: 2px solid #6B74C6;
border-bottom: 0px;
background-color: #F3F3F3;
color: #0378D9;
text-decoration: none;
}
<ul class="tablist">
<li ng-repeat="tab in tabList" ng-click="setSelected($index);" ng-class="{ selectedTab: $index === selected}">
{{tab.title}}
</li>
</ul>