I have a customised combo box component, i wanted to add style to the highlighted item and the selected item. I want to add beside the selected one but it is always showing to the first item, what is wrong here?
enter image description here
.combobox-option {
padding: 0.25em 0.5em;
cursor: pointer;
&.selected {
background-color: red;
color: var(--color-white);
&::after {
content: " ";
cursor: pointer;
display: block;
position: absolute;
top: 0;
right: 0;
width: 25px;
height: 25px;
background-image: url(../check.svg);
background-repeat: no-repeat;
background-position: right;
background-size: contain;
}
}
&.highlighted {
background-color: var(--color-bg-blue);
color: var(--color-white);
}
}
<li
tabIndex={0}
className={clsx(
"combobox-option",
option.value === search && "selected",
index === highlightedIndex && "highlighted",
)}
key={option.label}
onClick={() => {
optionSelected(index);
setIsOpen(false);
}}
>
<span>{option.value}</span>
</li>
You seem to be missing a relatively positioned ancestor of the pseudo element. Most likely you should add position: relative to the .combobox-option class description — thus the CSS would know in relation to which element it should position your checkmark icon. Otherwise it would stick to the closest element with a position different from default static — or, if none is present on a page, to the very top of the document. Hope it helps!
Related
This question already has answers here:
Thick underline behind text
(7 answers)
Closed 8 months ago.
I am trying to use a background color on text only, which works fine on single lines, but when the line breaks in responsive mode it ends up looking like this:
Does anyone know what to add to make the yellow background line follow the text on mulitple lines?
This is my code:
.background-highlight {
position: relative;
display: inline-block;
color: #faf9f4;
}
.background-highlight:after {
content: '';
position: absolute;
width: 100%;
height: 10px;
left: 0;
top: 50%;
background-color: #cef230;
z-index: -1;
}
Thanks a lot in advance,
I have used box-decoration-break: clone; property for mainting the same design for multiple lines don't forget to add display: inline; to its child where background is added. in child I have used linear gradient you can generate according to you from here. you can chenge the position of green strip by adjusting gradient values from the site.
.background-highlight {
position: relative;
display: inline-block;
color: #000;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
font-size: 120px;
}
.background-highlight span {
display: inline;
background: rgb(206,242,48);
background: -webkit-gradient(linear, left bottom, left top, color-stop(11%, rgba(206,242,48,1)), color-stop(12%, rgba(255,255,255,0)));
background: -o-linear-gradient(bottom, rgba(206,242,48,1) 11%, rgba(255,255,255,0) 12%);
background: linear-gradient(0deg, rgba(206,242,48,1) 11%, rgba(255,255,255,0) 12%);
}
<h1 class="background-highlight"><span>The skippers escape</span></h1>
It is fault of pseudo element that is forced to break between two lines.
The cause is the way the effect is carried out, pseudo element ::before creates a single rectangle that has no way of splitting up to follow words flow. Posible solutions:
Make sure links never occupy more than 1 line. You can use
white-space: nowrap;
Redesign the effect applying box border to main element. For example:
.background-highlight {
width: max-content;
border-bottom:5px solid rgb(217, 255, 0);
}
<div class="background-highlight">THE SKIPPER´S ESCAPE</div>
Pseudo-element solution
Use the bottom-positioning value on the pseudo-element instead of top. This forces the pseudo-element to be positioned at the bottom, instead of 50%from the top. I used bottom: -10px as that is the height of the pseudo-element, so it aligns perfectly.
Read more on position values: https://developer.mozilla.org/en-US/docs/Web/CSS/position
HTML-element solution
Instead of creating a pseudo-element, you could opt to make an HTML element instead.
Make a parent container, apply flex to it so the text and the line will align.
Make the .line-element a block element, so it will break into a new line.
You can still apply position: absolute and position: relative on the .line and the h2 if you want to position it in another way. Or you could simply use e.g. transform: translateY(5px) to move the line up a bit.
.background-highlight {
position: relative;
display: inline-block;
color: black;
text-align: right;
}
.background-highlight:after {
content: '';
position: absolute;
width: 100%;
height: 10px;
left: 0;
bottom: -10px;
background-color: #cef230;
z-index: -1;
}
/* Without pseudo */
.nopseudo {
display: flex;
}
.nopseudo h2 {
text-align: right;
}
.nopseudo .line {
height: 10px;
width: 100%;
background-color: #cef230;
display: block;
}
<h2 class="background-highlight">The Skippers <br>Escape</h2>
<div class="nopseudo">
<h2>The Skippers <br>Escape<span class="line"></span></h2>
</div>
I don't know how is your structure but this might help.
We just need two div elements, one as a container to setup the width property and the text holder in this case I will use a h2 tag.
Just mkae the ::after pseudo element as display and the .background-highlight's width can be width: match-content or 100% in this case if you just want to cover the text use match-content if you want to cover the width of the .title element use 100%
.title {
width: 90vw;
text-align: end;
}
h2 {
text-transform: uppercase;
color: #374650;
}
.fullwidth {
width: 100%;
}
.match {
width: match-content;
}
.background-highlight {
position: relative;
display: inline-block;
}
.background-highlight:after {
content: '';
display: block;
width: 100%;
height: 10px;
background-color: #cef230;
z-index: -1;
}
<div class="title">
<h2 class="match background-highlight">
The Skipper's <br>Escape</h2>
</div>
<div class="title">
<h2 class="fullwidth background-highlight">
The Skipper's <br>Escape</h2>
</div>
I am trying to build a custom dropdown component for React. Unfortunately, my child list's width, which I have set to 100%, is showing up as wider than its parent element.
The DOM:
<div className="dd-wrapper" id={this.state.wrapperID}>
<div className="dd-header" id={this.state.headerID} onClick={() => this.toggleList()}>
<div className="dd-header-title"></div>
</div>
<ul className="dd-list hidden" id={this.state.listID}>
<li className="dd-list-item">Test</li>
<li className="dd-list-item">Test2</li>
<li className="dd-list-item">Test3</li>
</ul>
</div>
the toggleList function removes the hidden class from the list, and adds a border property class dd-border to the wrapper, which is also not behaving properly (the border is wrapping only the header).
It is being called in the parent element like this (I am using Bootstrap grid):
<div className="col-md-3">
<label> Dropdown
<Dropdown id="test-dd"/>
</label>
</div>
Here's the relevant css:
.dd-wrapper {
width: 100%;
margin-top: 8px;
}
.dd-header {
height: 40px;
background-color: #E2E8F2;
background-image: url("assets/images/down-chevron.png");
background-repeat: no-repeat;
background-position: 95% 50%;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
}
.dd-list li {
height: 40px;
}
.dd-border {
border: 1px solid #3d70b2;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.hidden {
display: none;
}
The result looks like this:
How can I get the width to match its parent without doing it manually (to ensure it will work for any size of dropdown? And, secondarily, does anyone know a good trick for getting the border to cover the child as well?
A quick note: This is a CSS question so your React logic is just acting as a hurdle for anyone willing to answer. I've extracted the important parts based on your description into a working snippet below without React. I would recommend pulling out anything not crucial to the context of your questions to encourage more prompt answers.
How can I get the width to match its parent without doing it manually (to ensure it will work for any size of dropdown?
I think the main thing you are looking for is position: relative on the parent. Because absolutely positioned elements size and position themselves against the first "positioned" ancestor. As a result, you can then combine this with top, left, right, bottom, width and/or height values (and probably box-sizing: border-box;)
...does anyone know a good trick for getting the border to cover the child as well?
You can fake it by putting the dropdown right up against the bottom and toggling a class on a common parent to hide/show certain borders.
Here's the snippet to demonstrate:
// The toggle logic in vanilla JS just to make the example work
// This, instead of toggling "hidden" on the list, toggles a "dd-closed" class on the wrapper
const wrapperEl = document.querySelector('.js-wrapper')
const headerEl = document.querySelector('.js-header')
if (wrapperEl && headerEl) {
const ancestorLabel = headerEl.closest('label')
const targetEl = ancestorLabel ? ancestorLabel : headerEl
targetEl.addEventListener('click',
() => wrapperEl.classList.toggle('dd-closed')
)
}
.dd-wrapper {
position: relative;
width: 100%;
margin-top: 8px;
}
.dd-header {
position: relative;
height: 40px;
background-color: #E2E8F2;
background-repeat: no-repeat;
background-position: 95% 50%;
border: 1px solid #3d70b2;
border-bottom-width: 0;
padding-right: 3em;
}
.dd-header::before {
position: absolute;
content: '\25B4';
right: 0;
text-align: center;
line-height: 40px;
width: 1em;
top: 0;
bottom: 0;
font-size: 2em;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
border: 1px solid #3d70b2;
margin-top: 0;
left: 0; right: 0;
padding: 0;
}
.dd-list li {
vertical-align: middle;
padding: 1em;
}
.dd-list li:hover {
background-color: #eee;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.dd-closed > .dd-header::before {
content: '\25BE';
float: right;
}
.dd-closed > .dd-header {
border-bottom-width: 1px;
}
.dd-closed > .dd-list {
display: none;
}
<!-- Basically what React would render as your output HTML...plus any necessary changes -->
<label> Dropdown
<div class="dd-wrapper dd-closed js-wrapper">
<div class="dd-header js-header">
<div class="dd-header-title"></div>
</div>
<ul class="dd-list">
<li class="dd-list-item">Test</li>
<li class="dd-list-item">Test2</li>
<li class="dd-list-item">Test3</li>
</ul>
</div>
</label>
<p>(Some other content for the dropdown to cover)</p>
<button>(I do nothing)</button>
Inside my Pen you can see an image block with a title on the bottom. When the user hovers over the block, a description is shown on the bottom and the title is moved.
However, the title is on the correct location if the description contains 1 line of text. With 2 lines of text, the title is on top the description. How could I have the title always just above the description, without moving it all the way to the top of the block?
.trend-block {
position: relative;
width: 150px;
height: 150px;
&:hover {
.transition-title {
bottom: 35px;
}
.trend-text {
display: inline-block;
width: 120px;
color: red;
position: absolute;
bottom: 15px;
padding: 0 15px;
}
}
}
.trend-image {
width: 100%;
height: 100%;
}
.trend-title {
font-weight: bold;
color: red;
position: absolute;
bottom: 15px;
padding: 0 15px;
}
.trend-text {
display: none;
}
.transition-title {
transition: bottom .1s ease;
}
You could make a wrapper class absolute instead of the two spans (.trend-content); https://codepen.io/anon/pen/jxxbpx. The .trend-text does now have a max-height of zero as default. When you hover over it, the max-height will be te same as te container (Can't be a height of auto in order to make the transition).
I'm trying to add an icon inside a button. The problem is that whenever I add the icon, it changes the shape of the button (it makes it taller, and sometimes wider depending on how big the icon is), and it mis-aligns the text of the button so that it is no longer centered, rather the text has been pushed down.
<button>
<i class="material-icons">weekend</i>
Test
</button>
And the CSS:
i {
color: #669FAB;
font-size: 24px !important;
}
button {
min-width: 100px;
}
https://jsfiddle.net/uxs71ymz/1/
I would like the icon to shift to the left, while having the text remain centered inside the button.
hi here is the css code
CSS
i {
color: #669FAB;
font-size: 24px !important;
vertical-align:middle;
}
button {
min-width: 100px;
}
hope this helps..
https://jsfiddle.net/hq9t8rk4/
button i.material-icons {
color: #669FAB;
font-size: 24px;
// Add the below
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
}
button {
min-width: 100px;
// Add the below
position: relative;
padding: 3px 50px;
line-height: 24px;
text-align: center;
}
I'm trying to use the background link css property selector within WordPress for the image appear on it's page http://launique.co.uk/services-float/
First I used the default image link and entered the link to the default image, which I had uploaded to the media library:
background: url(http://launique.co.uk/wp-content/uploads/2016/07/fold.gif) no-repeat 0 0;
That didn't work.
Then after some research, I created a separate "images" folder within the child themes folder in my cpanel.
background: url(images/fold.gif) no-repeat 0 0;
But still to no avail...
This is the whole like of code:
.page-services h1::after {
content: '';
display: block;
height: 40px;
width: 40px;
background: url(images/fold.gif) no-repeat 0 0;
}
UPDATED: This should definitely work.
.page-services {
display: block;
position: relative;
}
.page-services h3::after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
height: 40px;
width: 40px;
background: url('http://launique.co.uk/wp-content/uploads/2016/07/fold.gif') no-repeat;
}
I inspected the HTML code on your site and I didn't find a H1 child elememt in the parent element div.page-services. Therefore your CSS rule will not work. There is, however, an H3 child element. When I altered your code in the debugger to .page-services h3::after{ ... } the image appeared.