When I'm hovering content inside div I'm getting offsets toward right side, I know that's because I'm adding left border, but how can I avoid this?
ul li:hover {
border-left: 4px solid #FF2F5A;
}
https://jsfiddle.net/eeeek/j8xaru7m/
While one can set a transparent border for the non-hovered state, that might sometimes given unwanted alignment.
Here is a solution using a pseudo element that overcomes that. The position: relative; on the ul li is necessary for the absolute positioned pseudo to position itself properly.
ul li {
position: relative; /* added property */
margin-left: -26px;
list-style-type: none;
width: 491px;
height: 50px;
border-bottom: 1px solid #F2F2F2;
}
ul li > span {
line-height: 40px;
margin-left: 30px;
}
ul li:hover::before { /* updated rule */
content: '';
position: absolute;
top: 0; left: 0; bottom: 0;
width: 4px; background: #FF2F5A;
}
.items {
position: absolute;
margin-left: -17.7px;
}
.block-with-items-style {
margin-left: 50px;
height: 400px;
width: 300px;
border: 2px solid #f2f2f2;
box-shadow: 2px 2px 10px #adadad;
resize: vertical;
overflow: hidden;
}
<div class="block-with-items-style">
<div class="items">
<ul>
<li ng-repeat="record in records">
<span>1</span>
<span class="badge badge-style">2</span>
<button class="delete" ng-click="Delete($index)">3</button>
</li>
</ul>
</div>
</div>
Bonus: This way one can easily add an animation as well
ul li {
position: relative; /* added property */
margin-left: -26px;
list-style-type: none;
width: 491px;
height: 50px;
border-bottom: 1px solid #F2F2F2;
}
ul li > span {
line-height: 40px;
margin-left: 30px;
}
ul li::before { /* added rule */
content: '';
position: absolute;
top: 50%; left: 0; bottom: 50%;
width: 4px; background: #FF2F5A;
transition: top .5s, bottom .5s;
}
ul li:hover::before { /* updated rule */
top: 0; bottom: 0;
}
.items {
position: absolute;
margin-left: -17.7px;
}
.block-with-items-style {
margin-left: 50px;
height: 400px;
width: 300px;
border: 2px solid #f2f2f2;
box-shadow: 2px 2px 10px #adadad;
resize: vertical;
overflow: hidden;
}
<div class="block-with-items-style">
<div class="items">
<ul>
<li ng-repeat="record in records">
<span>1</span>
<span class="badge badge-style">2</span>
<button class="delete" ng-click="Delete($index)">3</button>
</li>
</ul>
</div>
</div>
Just create invisible (100% alpha) border with previous css directive. As long hover is active – it will overwrite that transparent border with red. Here's the code:
ul li {
margin-left: -26px;
list-style-type: none;
width: 491px;
height: 50px;
border-bottom: 1px solid #F2F2F2;
}
ul li > span {
line-height: 40px;
margin-left: 30px;
}
/* Sylogista's upgrade begin */
ul li:not(:hover)
{
border-left: 4px solid rgba(255,255,255,0);
}
/* Sylogista's upgrade end */
ul li:hover {
border-left: 4px solid #FF2F5A;
}
.items {
position: absolute;
margin-left: -17.7px;
}
.block-with-items-style {
margin-left: 50px;
height: 400px;
width: 300px;
border: 2px solid #f2f2f2;
box-shadow: 2px 2px 10px #adadad;
resize: vertical;
overflow: hidden;
}
<div class="block-with-items-style">
<div class="items">
<ul>
<li ng-repeat="record in records">
<span>1</span>
<span class="badge badge-style">2</span>
<button class="delete" ng-click="Delete($index)">3</button>
</li>
</ul>
</div>
</div>
:not(:hover) is optional. Code will work good without it, but in my opinion – using that can be good practice. When? That's not place for debate, but let me give one short example in the margin of that answer: when you're creating huge css using many of states in that way and relations between elements – it just looks clearer.
In that case it's clearer maybe without it, but I'll not change that. Even just because of that not so many people use :not or even remember about that.
Related
To make sure the media query was actually working and the problem not being me setting the wrong max-width, I set the nav bar to change color and height when the max width was reached. My main goal was for the search bar to move further to the left but this doesn't work (the change in background color was for visual purposes). Why is this so? I'm trying to reposition the search bar as it glitches once the screen gets smaller.
nav ul {
display: inline-flex;
list-style: none;
transform: translate(16%);
}
nav ul li {
margin-right: 50px;
}
.search {
border-radius: 40px;
background-color: rgb(255, 255, 255);
display: inline-flex;
height: 35px;
transform: translate(180px, -1px);
}
.search input {
position: relative;
left: 10px;
top: 0px;
outline: none;
width: 0px;
border: none;
background: transparent;
transition: 0.5s;
}
search:hover input {
width: 150px;
}
.btn {
height: 35px;
width: 35px;
border-radius: 35px;
background-color: lightseagreen;
}
.btn i {
position: Relative;
top: 9px;
left: 9px;
}
#media screen and (max-width: 1380px) {
nav {
background-color: greenyellow;
height: 40px;
}
.search {
background-color: indigo;
}
}
<nav>
<ul>
<li><a href=#>word1</a></li>
<li><a href=#>word2</a></li>
<li><a href=#>word3</a></li>
</ul>
<div class="search">
<input type="text" placeholder="search">
<div class=btn>
<i class="fas fa-search"></i>
</div>
</div>
</nav>
Your media query is working as expected: The background-colors are applied and the height is set. The background-color for .search wasn't so good visible because the search input has a width: 0px - therefor i tested with 50px. The change of the height wasn't visible because everything was white - therefor i tested with:
nav {
background-color: #ccc;
}
Now you can see that on big screens the nav has no height (= auto) and on small screens 40px (use the browsers dev tools).
Working example:
nav {
background-color: #ccc;
}
nav ul {
display: inline-flex;
list-style: none;
transform: translate(16%);
}
nav ul li {
margin-right: 50px;
}
.search {
border-radius: 40px;
background-color: lightcoral;
display: inline-flex;
height: 35px;
transform: translate(180px, -1px);
}
.search input {
position: relative;
left: 10px;
top: 0px;
outline: none;
width: 0px;
border: none;
background: transparent;
transition: 0.5s;
}
.search:hover input {
width: 150px;
}
.btn {
height: 35px;
width: 35px;
border-radius: 35px;
background-color: lightseagreen;
}
.btn i {
position: Relative;
top: 9px;
left: 9px;
}
#media screen and (max-width: 1380px) {
nav {
background-color: greenyellow;
height: 40px;
}
.search {
background-color: indigo;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
<nav>
<ul>
<li><a href=#>word1</a></li>
<li><a href=#>word2</a></li>
<li><a href=#>word3</a></li>
</ul>
<div class="search">
<input type="text" placeholder="search">
<div class=btn>
<i class="fas fa-search"></i>
</div>
</div>
</nav>
Alternative example:
with display: flex for the whole nav container and deactivated transform for the ul in the media query
nav {
display: flex;
justify-content: space-between;
background-color: #ccc;
}
nav ul {
display: inline-flex;
list-style: none;
transform: translate(16%);
}
nav ul li {
margin-right: 50px;
}
.search {
border-radius: 40px;
background-color: lightcoral;
display: inline-flex;
height: 35px;
}
.search input {
position: relative;
left: 10px;
top: 0px;
outline: none;
width: 0px;
border: none;
background: transparent;
transition: 0.5s;
}
.search:hover input {
width: 150px;
}
.btn {
height: 35px;
width: 35px;
border-radius: 35px;
background-color: lightseagreen;
}
.btn i {
position: Relative;
top: 9px;
left: 9px;
}
#media screen and (max-width: 1380px) {
nav {
background-color: greenyellow;
height: 40px;
}
nav ul {
transform: none;
}
.search {
background-color: indigo;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
<nav>
<ul>
<li><a href=#>word1</a></li>
<li><a href=#>word2</a></li>
<li><a href=#>word3</a></li>
</ul>
<div class="search">
<input type="text" placeholder="search">
<div class=btn>
<i class="fas fa-search"></i>
</div>
</div>
</nav>
If it is not working for all the div's, check if you forgot to put <meta content="width=device-width, initial-scale=1" name="viewport" /> inside your <head> </head> tags where you have your HTML code. This should do the trick.
I am trying to make a dropdown box with submenus appearing horizontally, which can also scroll vertically.
I have gotten everything working except for the scroll.
.dropdown-container {
background: white;
border: 1px solid #666;
cursor: pointer;
line-height: 24px;
height: 24px;
position: relative;
width: 150px;
}
.dropdown-container a {
color: black;
padding: 0 10px;
text-decoration: none;
}
.dropdown-container:after {
color: #666;
content: '\f107';
font-family: FontAwesome;
position: absolute;
right: 2px;
top: 0px;
}
.dropdown-container:before {
content: attr(data-content);
padding: 0 10px;
}
.dropdown-container li > a:not(:only-child):after {
content: '\f105';
font-family: FontAwesome;
position: absolute;
right: 4px;
top: 0px;
}
.dropdown-container ul {
background: white;
border: 1px solid #666;
display: none;
right: 1px; /*Why is it being nudged 1px right relative to parent?*/
list-style: none;
margin: 0;
max-height: 80px;
overflow-x: visible;
overflow-y: auto; /*This is the problematic line, remove this and the rest works*/
padding: 0;
position: relative;
width: 100%;
}
.dropdown-container:hover > ul {
display: block;
}
.dropdown-container ul li {
background: white;
position: relative;
}
.dropdown-container ul li:hover {
background: rgba(173, 216, 230, 0.6);
}
.dropdown-container ul li:hover > ul {
display: block;
}
.dropdown-container ul ul {
display: none;
position: absolute;
left: 150px;
width: 150px;
top: -1px; /*Another 1px adjustment required, why aren't they already aligned?*/
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<div class="dropdown-container" role="nav" data-content="Title">
<ul class="dropdown">
<li>
Select 1
</li>
<li>
Select 2
<ul>
<li>
Select 2.1
<ul>
<li>
Select 2.1.1
</li>
</ul>
</li>
<li>
Select 2.2
</li>
</ul>
</li>
<li>
Select 3
</li>
<li>
Select 4
</li>
</ul>
</div>
See JSfiddle here.
But if I set overflow-y on the <ul> to auto to enable scrolling then my submenus get hidden as in the snippet above.
I believe the problem is the same as in this question: when overflow-y: auto and overflow-x: visible, overflow-x is treated as auto too.
Unfortunately the solution suggested (wrapping the <ul> in a position: relative element) has not worked for me.
Does anyone know of another way around this?
I am trying to use CSS to expand the input box on hover/focus of the search ICON of CSS
Now, I am trying to call a function in html to angular component (seems that I cannot use CSS with datalist element) such that the input tag gets stays expanded when I shift the focus or select an item from datalist
Here is my sample HTML
<div class="searchDiv">
<span class="glyphicon glyphicon-search" id="searchSpan" (click)="searchEvent($event)"></span>
<form [formGroup]="searchGroup" (ngSubmit)="searchEvent($event)">
<input type="text" placeholder="search" id="searchInput" formControlName="localInput" class="" list="promotionsSearchList"
(keyup)="searchEvent($event)" />
</form>
<datalist id="promotionsSearchList" class="test"
onfocus="focusEvent()" onmousemove="focusEvent()">
</datalist>
</div>
Here is my CSS
.customClass {
float: center;
}
.grid {
display: inline-grid;
grid-template-columns: 150px 150px 150px 150px auto;
grid-template-rows: repeat(3,25px);
width: 100%;
}
#headerDiv {
grid-row : 1;
grid-column : 1/6;
padding-top: 14px;
}
#firstElementSpan {
grid-row:1;
grid-column:2/6;
}
#secondElementSpan {
grid-row:1;
grid-column:3/6;
}
#thirdElementSpan {
grid-row:1;
grid-column:4/6;
}
#fourthElementSpan {
grid-row:1;
grid-column:5/6;
}
.rounded-text-box{
border-radius: 2px;
border: 2px solid #555;
padding: 20px;
width: 200px;
height: 15px;
}
.searchDiv{
width: 500px;
vertical-align: middle;
white-space: nowrap;
position: relative;
}
.searchDiv input#searchInput{
width: 45px;
height: 30px;
background: white;
border: none;
font-size: 10pt;
float: left;
color: black;
/*this is to accomadate the search icon */
padding-left: 45px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.searchDiv #searchSpan{
/*the position needs to be mentioned as absolute for the icon to
appear on top of the input */
position: absolute;
top: 5%;
margin-left: 17px;
margin-top: 7px;
/*for now z index is mentioned as to make the icon on top */
/* z-index: 5; */
z-index : 1;
color: #4f5b66;
background-color: inherit;
}
.searchDiv input#searchInput:hover, .searchDiv
input#searchInput:focus, .searchDiv input#searchInput:active{
outline:none;
width:300px;
}
.searchDiv:hover input#searchInput{
width:300px;
}
.searchDiv:hover #searchSpan{
color: #93a2ad;
}
/* this is not working , hence tried to use get the element in
angular and change its DOM prop*/
datalist:active, datalist:focus input#searchInput{
width:300px;
}
This is my sample angular component call. I have just reduced to the point of func call at this point
focusEvent(){
console.log('onfocusEvent');
const inputElement = document.getElementById('searchInput');
inputElement.style.width = '300px';
}
I don't see the func being called. I tried to use angular's property binding as well but no luck. basically I want the input element to keep expanded when I have shift the focus to the datalist element and going through the list. Could you guys help?
Thanks to #CBroe to notifying this. We cannot listen to any events as well as not do any modifications using datalist. Hence I started using ul
Here is a sample html code modified:
<div class="searchDiv">
<span class="glyphicon glyphicon-search" id="searchSpan" (click)="searchEvent($event)"></span>
<input type="text" placeholder="search" id="searchInput" class="" list="promotionsSearchList"
(keyup)="searchEvent($event)" [(ngModel)]="searchModel"/>
<ul *ngIf="loadDropDown">
<li *ngFor="let pp of promoList" (click)="selectAnyItem($event)" value="pp.id"><span>{{pp.name}}</span>
</li>
</ul>
</div>
Here is the CSS that I implemented.
ul {
padding: 2px;
list-style-type: none;
z-index:2;
background-color:black;
/*below css makes the element clear the float and move to the next
line if placed in the same block */
clear:both;
}
li:hover{
background-color: dodgerblue;
}
.rounded-text-box{
border-radius: 2px;
border: 2px solid #555;
padding: 20px;
width: 200px;
height: 15px;
}
.searchDiv{
width: 500px;
vertical-align: middle;
white-space: nowrap;
position: relative;
}
.searchDiv input#searchInput{
width: 45px;
height: 30px;
background: white;
border: none;
font-size: 10pt;
float: left;
color: black;
/*this is to accomadate the search icon */
padding-left: 45px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.searchDiv #searchSpan{
position: absolute;
top: 5%;
margin-left: 17px;
margin-top: 7px;
z-index : 1;
color: #4f5b66;
background-color: inherit;
}
.searchDiv input#searchInput:hover, .searchDiv
input#searchInput:focus, .searchDiv input#searchInput:active{
outline:none;
width:300px;
}
.searchDiv:hover input#searchInput {
width:300px;
box-sizing:border-box;
}
.searchDiv:hover ul{
width:300px;
box-sizing: border-box;
}
.searchDiv:hover #searchSpan{
color: #93a2ad;
}
Hope this helps for the users who are trying to implement
Is the following result possible with CSS:
So that li.item takes 50% of the width of div.wrapper, not the ul.list (which is extremly long).
I've added a snippet of a basic setup. Any ideas on the matter are appreciated (please keep in mind I'm looking for CSS options). A jsfiddle playground link: http://jsfiddle.net/6o8t9t8L/
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 2000px;
}
.item {
display: inline-block;
height: 200px;
width: 50%;
border: 1px solid green;
}
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
I believe there are some 'workaround' solutions to your issue, so I'll pour in some of my ideas, maybe it will help you out a bit.
Idea 1: Position absolute and a bunch of :nth-child selectors
In order to make the .item have their width relative to .list wrapper, you can absolute position these items, and set .list wrapper to position relative, so that the .item width will be calculated based on .list width.
The major downfall of this idea would be that you have to position these elements next to each, like using the left property, but passing it like a loop:
first item will have left: 0;
second item will have left: 50%;
third item will have left: 100%;
and so on...+50% to the next items
You can either pour in a bunch of :nth-child(n), each with +50% left prop. from each other, OR use some sass stuff to make it faster.
Check out the demo here & sass demo here
*,
*:after,
*:before {
box-sizing: border-box;
}
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
/*make the grandparent, .wrapper, relative, so that the grandchilds, .item,
will calculate their width based on this width*/
position: relative;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 2000px;
margin: 50px 0;
padding: 0;
/*since everyone has position absolute, theres no content flow, so a fixed height
has to be supplied*/
height: 200px;
}
.item {
width: 50%;
border: 1px solid green;
position: absolute;
left: 0;
/*you can set a height here, or position them like I did bellow*/
top: 51px;
bottom: 51px;
}
/*now the fun part starts
somehow these .items have to have left: +50% for each of them, like a loop somehow,
so you can either pour in a lot of nth-child(), for how many children you think this
list is going to have, or use sass to write it faster like i did here:
*/
.item:nth-child(1) {
left: 0;
}
.item:nth-child(2) {
left: 50%;
}
.item:nth-child(3) {
left: 100%;
}
.item:nth-child(4) {
left: 150%;
}
.item:nth-child(5) {
left: 200%;
}
.item:nth-child(6) {
left: 250%;
}
.item:nth-child(7) {
left: 300%;
}
.item:nth-child(8) {
left: 350%;
}
.item:nth-child(9) {
left: 400%;
}
.item:nth-child(10) {
left: 450%;
}
.item:nth-child(11) {
left: 500%;
}
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
Idea 2: Display: flex
Using display: flex on .wrapper, will allow you to have the widths of the .item to be relative to their grandparent.
The major downfall of this idea would be that the width of .list element, will be overwritten by the width of .wrapper, no matter if you specify it or not. However, not all is lost, if you need that specific width for some styling, you can specify it, and use some pseudo classes with width: inherit, so they'll stretch to whatever width you specified in the first place.
Check out the demo here
*,
*:after,
*:before {
box-sizing: border-box;
}
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
/*bring on the awesomeness*/
margin: 20px;
}
.list {
list-style-type: none;
/*border: 1px solid red;*/
/*you can keep this defined width, items will calculte their width
based on .wrapper class, wich will overwrite this classes width,
however if you have some use for this width, consider using :after, :before
classes like I did bellow, with .list:before*/
position: relative;
z-index: 1;
width: 2000px;
white-space: nowrap;
margin: 20px 0;
padding: 0;
font-size: 0;
/*display inline block extra spacing ....*/
}
.list:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: inherit;
/*it will inherit the width you set above*/
border: 1px solid red;
}
.item {
display: inline-block;
vertical-align: top;
height: 200px;
width: 50%;
border: 1px solid green;
font-size: 16px;
/*bump back the font-size*/
}
<div class="wrapper">
<ul class="list">
<li class="item">a</li>
<li class="item">b</li>
<li class="item">c</li>
<li class="item">d</li>
</ul>
</div>
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
.wrapper {
width: 400px;
border: 1px solid black;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 400px;
display: block;
white-space:nowrap;
padding: 0;
margin: 0;
}
.item {
display: inline-block;
height: 200px;
width: 47%;
border: 1px solid green;
padding: 1%;
}
http://jsfiddle.net/btsewL9v/
I would suggest something like this..
EDIT:
I don't know how many items you are trying to cram into the list, but take a look at this:
http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/
I'm working on a new responsive design and I'm having an issue with my menu that I cannot figure out. Basically I want the background of the menu item to turn white when you hover over it and the text to turn blue. Right now, the text turns blue but the background will not turn white.
HTML Code:
<div class="header">
<div class="header_content">
<div class="logo">
<img src="images/new_logo.png" class="hdr_logo">
</div>
<div class="main_menu">
<ul>
<li>ABOUT US</li>
<li>OPERATIONS BRANCH</li>
<li>LOGISTICS BRANCH</li>
<li style="border-right:0;">COMMUNITY</li>
</ul>
</div>
</div>
</div>
CSS:
.header {
background: url('images/header2.png') repeat-x top left;
width: 100%;
height: 150px;
color: #FFF;
margin: 0;
padding: 0;
}
.header_content {
width: 960px;
margin: 0 auto;
height: 150px;
padding: 0;
}
.logo {
float:left;
width:120px;
}
.main_menu {
float:left;
height: 30px;
margin-top: 120px;
line-height: 30px;
padding: 0;
width: 830px;
}
.main_menu ul {
list-style-type: none;
padding: 0;
margin: 0;
text-align: center;
overflow: hidden;
height: 30px;
}
.main_menu li {
float: left;
border-right: 1px solid #FFF;
text-align: center;
padding: 0;
margin: 0;
padding-left: 2%;
padding-right: 2%;
overflow: hidden;
height: 30px;
cursor: pointer;
}
.main_menu li:hover {
background-image: none;
background-color: #FFF;
color: rgb(33,47,57);
}
EDIT: Problem Resolved
The floated li was not a block element so you could not change it's background color. As soon as I added display:block; to the li it resolved this issue.
Seems to work fine for me: http://jsfiddle.net/s3JT9/
.main_menu li:hover {
background-image: none;
background-color: #FFF;
color: red;
}
I changed the color to red to illustrate.