Working with Less: avoiding tree inheritance - less

When I want to write something like
.security-list ul {
list-style: none;
margin-left: 0;
}
.security-list ul li {
padding: 10px 9px;
display: inline-block;
}
.security-list ul li a {
width: 234px;
color: #000;
text-decoration: none;
display: inline-block;
background-image: url(http://domain.com/infopage-icons.png);
background-position: 200px 0;
background-repeat: no-repeat;
}
.security-list ul li a.basket,
.security-content h3.basket {
background-position: 200px 0;
}
.security-list ul li a.creditcard,
.security-content h3.creditcard {
background-position: 200px -205px;
}
I end up writting:
.security-list ul {
list-style: none;
margin-left: 0;
li {
padding: 10px 9px;
display: inline-block;
a {
width: 234px;
color: #000;
text-decoration: none;
display: inline-block;
background-image: url(http://domain.com/infopage-icons.png);
background-position: 200px 0;
background-repeat: no-repeat;
&.basket,
.security-content h3.basket {
background-position: 200px 0;
}
&.creditcard,
.security-content h3.creditcard {
background-position: 200px -205px;
}
}
}
but the problem I have is this will compile the last 2 blocks as
.security-list ul li a.basket,
.security-list ul li a .security-content h3.basket { ... }
.security-list ul li a.creditcard,
.security-list ul li a .security-content h3.creditcard { ... }
where what I really want is:
.security-list ul li a.basket,
.security-content h3.basket{ ... }
.security-list ul li a.creditcard,
.security-content h3.creditcard { ... }
What can I do in LESS that he knows that I do not want to inherit the hole tree, but still not repeat myself on the same style rule, in other words, don't create 2 rules with the same content...

Your problem is that you want to ignore the nest inside a nest, which is not (at least currently) possible. If it did work, it also would make for challenging code to read, as you would not expect a non-nesting item to be defined inside a nest.
I think one elegant solution to this, especially in your case, is to abstract the nest even further. This code gets close to what you desire by locating it all within a .security nest:
.security {
&-list ul {
list-style: none;
margin-left: 0;
li {
padding: 10px 9px;
display: inline-block;
a {
width: 234px;
color: #000;
text-decoration: none;
display: inline-block;
background-image: url(http://domain.com/infopage-icons.png);
background-position: 200px 0;
background-repeat: no-repeat;
}
}
}
&-list ul li a,
&-content h3 {
&.basket {
background-position: 200px 0;
}
&.creditcard {
background-position: 200px -205px;
}
}
}
The above disaccociates the call from the deep nesting in the list, which does require a small repetition of code in the ul li a call, but it produces this CSS:
.security-list ul {
list-style: none;
margin-left: 0;
}
.security-list ul li {
padding: 10px 9px;
display: inline-block;
}
.security-list ul li a {
width: 234px;
color: #000;
text-decoration: none;
display: inline-block;
background-image: url(http://domain.com/infopage-icons.png);
background-position: 200px 0;
background-repeat: no-repeat;
}
.security-list ul li a.basket,
.security-content h3.basket {
background-position: 200px 0;
}
.security-list ul li a.creditcard,
.security-content h3.creditcard {
background-position: 200px -205px;
}
Assuming the .security-list class is only used on a container that holds a true list (like a ul), then if you are able to remove the background-position from the straight security-list ul li a selector, you can then reduce the selector of the .basket and .creditcard by removing the ul li porition of that to make it just .security-list a.basket, etc. This would reduce the selector nesting bloat on that call.

Related

Apply rules to list of parent classes

I have the below LESS stylesheet and I know there has to be a better way to organize this. Is the only option to create a map containing the classes and a mixin perhaps to repeat the styles?
// child div is injected by JS
.ddemrcontent > span, .blocksmarttemplate > span, .blocktoken > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
}
.ddfreetext {
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
}
.ddemrcontent > span:hover, .blocksmarttemplate > span:hover, .blocktoken > span:hover {
text-decoration: underline;
cursor: pointer;
}
.ddemrcontent > span {
border-left: 4px solid cadetblue;
}
.blocksmarttemplate > span {
border-left: 4px solid burlywood;
}
.blocktoken > span {
border-left: 4px solid #8a7090;
}
.ddfreetext {
border: 1px dashed black;
}
UPDATE
Here is the best I've been able to come up with. Since the & parent selector won't apply to each distinct parent selector (that are comma delimited) I think I am forced to use a mixin and call it to apply the rules for each parent I have.
Would love to hear if there's still a better way.
.dyndoccontent(#color) {
& > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
border-left: 4px solid #color;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
}
// child div is injected by JS
.ddemrcontent {
.dyndoccontent(cadetblue);
}
.blocksmarttemplate {
.dyndoccontent(burlywood);
}
.blocktoken {
.dyndoccontent(#8a7090);
}
.ddfreetext {
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
border: 1px dashed black;
}
I would definitely recommend mixin if you have multiple parts in your less files which use the same styles.
For you example i would go for a more nested way:
// child div is injected by JS
.ddemrcontent, .blocksmarttemplate, .blocktoken {
& > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
}
.ddfreetext {
border: 1px dashed black;
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
}
.ddemrcontent > span {
border-left: 4px solid cadetblue;
}
.blocksmarttemplate > span {
border-left: 4px solid burlywood;
}
.blocktoken > span {
border-left: 4px solid #8a7090;
}

Button stays focused (hover) after clicked

I'm using bootstrap and vue 2.0.
It works normally when I don't click the button. It focus on #mouseenter and unfocus on #mouseleave like this.
But when I clicked button, it stay focused like this until I make another click anywhere, even in another window.
How can I fix this? Here is HTML and CSS code.
Button html:
<button class="btn btn-primary" v-on:click="search()"
type="button">{{$lang.ticketsSearch}}</button>
Button css:
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn:hover,
.btn:focus,
.btn.focus {
color: #333;
text-decoration: none;
}
.btn:active,
.btn.active {
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
cursor: not-allowed;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
opacity: .65;
}
a.btn.disabled,
fieldset[disabled] a.btn {
pointer-events: none;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary:focus,
.btn-primary.focus {
color: #fff;
background-color: #286090;
border-color: #122b40;
}
.btn-primary:hover {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active:hover,
.btn-primary.active:hover,
.open > .dropdown-toggle.btn-primary:hover,
.btn-primary:active:focus,
.btn-primary.active:focus,
.open > .dropdown-toggle.btn-primary:focus,
.btn-primary:active.focus,
.btn-primary.active.focus,
.open > .dropdown-toggle.btn-primary.focus {
color: #fff;
background-color: #204d74;
border-color: #122b40;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
background-image: none;
}
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus {
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary .badge {
color: #337ab7;
background-color: #fff;
}
When that button is clicked, it takes on the :focus state. If you don't want it to behave like that, you'd have to overwrite the focus state, but that's probably not a good idea. You could look into programmatically putting the focus on something else.
In this particular case to remove the "green" when you click and move away, you should only need to do:
.btn-primary:focus,
.btn-primary.focus {
color: #fff;
background-color: #000; /*this is where the colour was green*/
border-color: #122b40;
}

Transform:translate positioning wrong Internet Exploerer

I am using a number of Pseudo elements throughout a website I am building. They all look great except in IE. I am testing it in IE 10 and 11 to start off with.
For some reason the positioning is always slightly off - in the example below, about 5 px for each element.
I have tried changing the display and positions, setting the origins, but nothing seems to work.
Any help would be appreciated.
.home .welcome-row h1 {
position: relative;
margin-bottom: 0;
}
.home .welcome-row h1:before {
background-image: url('/wp-content/uploads/2017/10/welcome-line-1.png');
-webkit-transform: translateY(-23px);
-moz-transform: translateY(-23px);
-o-transform: translateY(-23px);
transform: translateY(-23px);
background-size: 260px 13px;
background-repeat: no-repeat;
width: 260px;
height: 13px;
content:"";
position: absolute;
display: block;
}
.home .welcome-row h1:after {
background-image: url('wp-content/uploads/2017/10/welcome-line-2.png');
-webkit-transform: translateY(5px);
-moz-transform: translateY(5px);
-o-transform: translateY(5px);
transform: translateY(5px);
background-size: 260px 13px;
background-repeat: no-repeat;
width: 260px;
height: 13px;
content:"";
position: absolute;
display: block;
}
*EDIT - I have added any additional theme styles that are applied incase they have any relevance.
*:after,
*:before {
box-sizing:border-box
}
:-webkit-any(article,aside,nav,section) h1 {
-webkit-margin-before: 0.83em;
-webkit-margin-after: 0.83em;
}
user agent stylesheet
h1 {
-webkit-margin-before: 0.67em;
-webkit-margin-after: 0.67em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
}
h1 {
margin: 0;
padding: 0;
}

Bootstrap collapse nav at 991px

Building a site using Bootstrap. Having an issue with the van. I want it to collapse at 991px. Searched online and found this code, however it has changed the function of the nav as the nav wont stay open. Any ideas? The code used to override default is in my custom.css
http://nurdit.com/styleengineered/
#media (max-width: 991px) {
.navbar-header {
float: none;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
margin: 7.5px -15px;
}
.navbar-nav>li {
float: none;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
}
Try changing the CSS above to:
#media (max-width: 991px) {
.navbar-header {
float: none;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
margin: 7.5px -15px;
}
.navbar-nav>li {
float: none;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
.navbar-collapse.collapse.in { /* NEW */
display: block!important;
}
}
As far as I can tell, this does the trick on your site. Credit for this suggestion goes to Dave Forber , see Bootstrap 3 Navbar Collapse

Why doesn't :active or :focus work on text links in webkit? (safari & chrome)

I think I'm overlooking something, call it a long day, but why isn't this working? The styles found in the "li a:active, li a:focus" persist in Firefox and IE but not webkit. Does webkit only support the :focus pseudo class on form elements?
#footer ul li a {
color: #fff;
display: block;
font-size: 95%;
padding: 15px 15px 10px;
text-decoration: none;
}
#footer ul li a:hover {
color: #f00;
}
#footer ul li a:active, #footer ul li a:focus {
border-top: 1px #f00 solid;
color: #f00;
padding-top: 14px;
}
#footer ul li a:focus:hover {
cursor: default;
}
The :focus pseudo class is meant for form elements, so the Webkit implementation does not apply it to other elements unless a tabindex attribute is added to the tag.
http://nemisj.com/focusable/
Actually, the anchor element not being mouse-focusable is a long-standing bug, see https://bugs.webkit.org/show_bug.cgi?id=26856 for the reference.