Please look at my jsfiddle here - http://jsfiddle.net/ftuZ5/ . I know why the links won't work as the relative positioning I have used to create the link / menu backgrounds I want is covering the a element but I can't work out how to resolve the issue (having tried relative and z-index on the li and a elements, plus adding and extra div to span the a element using that to create the 'button' style background) but all to no avail.
li {
list-style: none;
}
.side-nav li {
padding-bottom: 3.125em;
width: 100%;
line-height: 1.25em;
text-align: center;
}
.side-nav a {
position: relative;
top: 1.75em;
z-index: -1;
display: block;
color: white;
text-decoration: none;
background: #c7cbaf;
-webkit-border-radius: 48px;
-moz-border-radius: 48px;
-ms-border-radius: 48px;
-o-border-radius: 48px;
border-radius: 48px;
padding-top: 1.375em;
padding-bottom: 0.75em;
text-transform: uppercase;
}
.responsive-side-nav {
background: transparent url(http://thewebbakery.co.uk/assets/graphics/responsive-icon-sml.png) no-repeat top center;
}
.interactive-side-nav {
background: transparent url(http://thewebbakery.co.uk/assets/graphics/interactive-icon-sml.png) no-repeat top center;
}
.ux-side-nav {
background: transparent url(http://thewebbakery.co.uk/assets/graphics/ux-icon-sml.png) no-repeat top center;
}
Can anyone help?
Here's a possible solution for you:
JSFiddle
<nav class="side-nav" role=navigation>
<ul>
<li><div id="responsive-side-nav" class="side-nav-image"></div>Responsive Web Design</li>
<li><div id="interactive-side-nav" class="side-nav-image"></div>Interactive Web Design</li>
<li><div id="ux-side-nav" class="side-nav-image"></div>User Experience</li>
</ul>
By wrapping the anchor tags around a new div for the images, the whole thing becomes clickable.
Then you can position the images as you wish (I've created a common class for each image):
.side-nav-image
{
width: 100%;
height: 50px;
margin-top: -50px;
}
The only downside to this is that the hit area for the button increases to fit the size of the image. But if you want the image to overlap, while having the whole thing clickable, I'm not sure that's possible.
You have to set the height and the width on the tags, if you display them as "blocks"
Related
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>
I have a link, with which i want use plus, which will change color on hover.
But in the past hour i cant figure out how to do this trick with spites.
Here is a link, nothing special
Find Out More!
My css code
.block a.plus {
background: url("images/plus.png") no-repeat 0% 40%;
background-position: 10px , 0px;
font-size: 12px;
padding-left: 25px;
}
.block a.plus:hover{
/*Just for example*/
background-position: -15px -1px;
}
And also plus img
CSS sprites are often vertical arranged, since this will enable you to display only a specific line in your sprite file. In order to use the sprite technique on horizontal arranged images you have to create a second element with a non-transparent background:
<a href="detailed.html" class="plus">
<span>Find Out More!</span>
</a>
.block a.plus {
background: url("images/plus.png") no-repeat 0% 40%;
background-position: 10px , 0px;
font-size: 12px;
display: inline-block;
padding-left: 16px; /* actual width of one icon */
}
.block a.plus:hover{
/*Just for example*/
background-position: 0 -16px;
}
.block a.plus span{
background-color: #fff;
}
If you don't want to use a second element you should rearrange your icons.
You can achieve this with the :before selector.
Find Out More!
a.plus {
position: relative;
padding-left: 25px;
}
a.plus:before {
position: absolute;
left: 0;
content: " ";
width: 15px;
height: 15px;
background: red url("images/plus.png") 10px 0 no-repeat;
}
The color red is just for testing, you can leave that one out. -10px 0 is the location of the image in the sprite (x y).
I have a parent div (nav) that is 1000px. Within that there is a child div (nav-drop-panel), and within that one another child (drop-panel-col). Basically, the drop-panel-col is a list of links in navigation. As there is a specific height, I can only add so many links before adding another column (so there's 1-4 drop-panel-col divs within nav-drop-panel).
I want the nav-drop-panel div to size itself according to the number of columns within it. So if there's only one, it's smaller than if there's 4. It will never exceed or even come close to the 1000px width of its parent div (nav). For some reason, if I don't set nav-drop-panel to a specific width (which makes it too big for one column), it assigns itself an arbitrary width and all of my columns are pushed down and it looks terrible.
I've tried a few solutions to other related questions from here, but nothing has worked so far.
My HTML:
<div class="nav-drop-panel">
<div class="drop-panel-col">
<a class="cat">Vehicle Graphics</a>
Pick-Up Truck
Van
Enclosed Trailer
Box Truck
SUV
Car
Boat
Bus
ScratchGuard Magnets
Vinyl Lettering and Graphics
<p></p>
</div>
</div>
My CSS:
#nav {
padding: 0;
margin: 0;
list-style: none;
width: 1000px;
z-index: 15;
font-family: Verdana,Arial,Helvetica,sans-serif;
/* position: absolute;
left: 0px;
top: 0px; */
}
#nav .nav-drop-panel {
background-color: #FFFFFF;
border-bottom: 3px solid #BBBBBB;
border-bottom-right-radius: 10px;
border-right: 3px solid #BBBBBB;
height: 431px;
margin-bottom: 0;
padding-bottom: 7px;
padding-top: 19px;
/* position: absolute;
top: -5px;
left: 218px; */
}
#nav .drop-panel-col {
color: #333333;
float: left;
font-family: Arial;
font-size: 14px;
padding-left: 24px;
}
#nav .drop-panel-col a{
color: #333333;
display: block;
font-weight: bold;
height: 19px;
margin-bottom: 5px;
margin-left: -4px;
padding-left: 30px;
padding-top: 0;
width: 202px;
}
Greatly appreciate any help or ideas, thanks. :)
EDIT: Just showing what I did to remove the positioning. I had just commented it out to see if it would at least expand, and work from there.
Absolutely-positioned elements are no longer part of the layout. The parent element has no idea where, or how large they are.
You need to use JavaScript to calculate all of this an adjust the size of the parent accordingly... or use a layout that doesn't use absolute positioning.
Adding display: inline-block; to .nav-drop-panel seemed to do the trick; I've also reduced the printed code slightly(margin-left, margin-top, etc reduced to margin: etc etc etc etc;). To see your unaltered, but working(as in just with the display: inline-block; added) version, click here.
I have a few css sprites for a rating system: http://i.imgur.com/qeb2b.png
When loading the thumbs
.thumb-down {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -13px;
width: 15px;
height: 16px;
}
.thumb-up {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -33px;
width: 15px;
height: 16px;
}
The only way I can get the thumbs to show up is if I do this:
Was this review helpful? |
If I remove all the then the thumbs disappear. If I leave only one then it shows a partial view of the sprite.
How can I display the sprite without the need of ?
by using float:left:
.thumb-down {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -13px;
width: 15px;
height: 16px;
float: left; /* OR float:right, depending on what you need */
}
.thumb-up {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -33px;
width: 15px;
height: 16px;
float: left;
}
As the links are inline elements, you can't specify the width and height for them. They get their size only from their contents, that's why the spaces gives them size.
I think that the best option for your use is to make the links inline-block elements. That way they are block elements so that they can have a specific width and height, but they are still inline elements in the text flow so that you don't have to change your markup.
.thumb-down {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -13px;
display: inline-block;
width: 15px;
height: 16px;
}
.thumb-up {
background: url('http://i.imgur.com/qeb2b.png') no-repeat -126px -33px;
display: inline-block;
width: 15px;
height: 16px;
}
The image is a background. But for the background to be visible, the element must have some height and width. In your case an empty tag has no height and width. You should make it display:block
Just use display: inline-block; in both of your CSS classes.
This is very odd to me, and although I've searched, everyone seems to have the opposite problem to me (a floated div shrinking)!
I have this page: http://www.tameside.gov.uk/test/news, which uses PHP to generate the divs at the top for various news stories, and it works fine. However the items (which are floated divs) are in a div which is floated left, which for some reason isn't shrinking to those items (which are it's only contents).
As far as I was aware, a floated div always shrunk to it's contents, but this particular one is expanding to 100% of the page it seems. I've coloured the background of the containing div in grey to show you what I mean.
I want it to shrink to the contents so that I could use a centering trick, and it would then center the div no matter how many divs are in the top news items. But because it's not shrinking, the trick obviously isn't working.
The CSS for each of the news item divs is below:
.news-top-item {
border-radius: 10px;
border-color: #3f7dae;
border-style: solid;
border-width: 2px;
float: left;
width: 19%;
text-align: center;
margin-right: 0.5%;
height: 13em;
padding-top: 0.5em;
cursor: pointer;
position: relative;
}
They've also got a span inside that has a little CSS attached to it to make the whole thing a link:
.news-top-item span {
display: inline;
position:absolute;
width:100%;
height:100%;
top:0;
left: 0;
z-index: 2;
background-image: url('/tmbc_images/include/1pixel.gif');
cursor: pointer;
}
I doubt that's interfering, but have put it in just in case.
The outer div has only 'float: left' and the background colour applied to it.
Any help would be much appreciated.
Thanks,
James
You shall remove float:left and use display:inline-block instead
.news-top-item {
border-radius: 10px;
border-color: #3f7dae;
border-style: solid;
border-width: 2px;
display:inline-block;
width: 19%;
text-align: center;
margin-right: 0.5%;
height: 13em;
padding-top: 0.5em;
cursor: pointer;
position: relative;
}
And add text-align:center in your containing div
width:100%;
height:100%;
is 100% of windows size ...
Try
width:auto;
height:auto;
use absolute units instead of percentages to define measurements for the inner elements:
.news-top-item {
border-radius: 10px;
border-color: #3f7dae;
border-style: solid;
border-width: 2px;
float: left;
width: 200px; /* <--- */
text-align: center;
margin-right: 2px; /* <--- */
height: 13em;
padding-top: 0.5em;
cursor: pointer;
position: relative;
}