How to make border-left above border-bottom? - css

I have a Bootstrap list-group that looks like:
This is my CSS:
$border: 1px solid rgba(0, 0, 0, 0.125);
.customer-orders-filters {
.list-group {
box-shadow: $card-box-shadow;
color: $text-color;
font-weight: bold;
.list-group-item {
border-left: none;
border-right: none;
border-bottom: $border;
&:first-child {
border-top: none;
}
&:last-child {
border-bottom: none;
}
&.active {
border-left: 5px solid $blue;
}
}
}
}
As you can see, the border-left bottom is not very right.
I tried to remove the border-bottom on the first-child, then add a border-top to the nth-child(2) but that doesn't work, the border-top is not present. I also tried to set a border-style: outset to the border-bottom of the first-child but without effect.
I would like that the border-left be totally above or totally under the border-bottom, but not half...
Do you know how could I fix it? Should I use a pseudo-element?

Consider using a background and border like below:
.box {
width:200px;
height:50px;
padding-left:5px;
border-bottom:2px solid red;
background:linear-gradient(blue,blue) left/5px 100% no-repeat;
}
<div class="box"></div>
Or the opposite:
.box {
width:200px;
height:50px;
padding-bottom:2px;
border-left:5px solid blue;
background:linear-gradient(red,red) bottom/100% 2px no-repeat;
}
<div class="box"></div>
You can also do with box-shadow:
.box {
width:200px;
height:50px;
padding-left:5px;
border-bottom:2px solid red;
box-shadow:5px 0 0 blue inset;
}
<div class="box"></div>

It looks like the problem is being caused by Bootstrap adding "margin-bottom: -1px;" to the .list-group-item class. Overwriting that rule (and moving the border line to the bottom) seems to fix the issue. (At least in Chrome, I didn't test other browsers.)
Ex:
.list-group-item {
border-left: none;
border-right: none;
border-top: $border !important;
border-bottom: 0;
margin-bottom: 0;
... etc ...
Pen: https://codepen.io/anon/pen/moyOGg
Note that making this change may have other consequences (the Bootstrap devs must have put that -1px margin rule in there for a reason) so you'll need to do some more testing!

Related

Add offset to border-bottom in CSS

I have a problem where I need to make a border-bottom, with a given offset in CSS
for example, in this JSFiddle, I have a black border-bottom.
https://jsfiddle.net/uexma4o6/343/
<div style="border-bottom: 2px solid black; width:500px; height:40px; background-color:lightcoral"></div>
but I want to give an offset to this 2px solid black border to be 5px above from where it is.
Is it possible?
This can be done with a linear-gradient:
.box {
background:
linear-gradient(black,black) 0 calc(100% - 5px)/100% 2px no-repeat,
lightcoral;
width: 500px;
height: 40px;
}
<div class="box"></div>
You can also do it like this:
.box {
background:
linear-gradient(black,black) bottom/100% 2px no-repeat,
lightcoral;
border-bottom:5px solid lightcoral;
width: 500px;
height: 40px;
box-sizing:border-box;
}
<div class="box"></div>
Another idea with box shadow:
.box {
background:lightcoral;
border-bottom:2px solid black;
box-shadow:0 5px 0 lightcoral;
width: 500px;
height: 40px;
}
<div class="box"></div>
And with inset shadow:
.box {
background:lightcoral;
box-shadow:
0 -5px 0 lightcoral inset,
0 -7px 0 black inset;
width: 500px;
height: 40px;
}
<div class="box"></div>
Solution
https://jsfiddle.net/StephanieSchellin/j7pmxkc3/
Use CSS ::after to add a pseudo element that has the border you are looking for. Then move the pseudo element around to position it how you like. This pseudo element will always be tied to its root element but you still have to take into account modifying it for #media query changes and such.
You see in the image below that this solution is layering the pseudo element over the root one. You can choose to use ::before or experiment with other positioning setups to accommodate your layout needs.
Always do plenty of cross browser testing when doing edge case things like this because its possible you will run into box model issues.
HTML
<div class='the-div'></div>
CSS
.the-div {
width:500px;
height:40px;
background-color:lightcoral;
position: relative
}
.the-div::after {
border-bottom: 2px solid black;
content: '';
width:500px;
position:absolute;
bottom:5px;
}
Further Reading
See https://css-tricks.com/pseudo-element-roundup/
There are lots of cool things you can do with pseudo elements.

CSS reverting to defined style

In my app a frequently used HTML component is styles as:
.box {
min-width: 100px;
padding: 20px 10px;
}
there are a lot of these (100+) and their border is styled without bottom and different by color:
.box:nth-child(1) {
border: 2px solid red;
border-bottom: none;
}
.box:nth-child(2) {
border: 2px solid green;
border-bottom: none;
}
.box:nth-child(3) {
border: 2px solid blue;
border-bottom: none;
}
.box:nth-child(4) {
border: 2px solid yellow;
border-bottom: none;
}
...
There's a page in the app where all these boxes need to be displayed with full border (including the bottom border) - what is needed is to remove the 'boder-bottom:none' definitions. So in this specific page I've tried to override the .box definition:
.box {
border-bottom: initial; /* tried unset as well...*/
}
But this still results with no border. Is there a way to specify a style so all the .box accepts the full border - or I have to redefine all of the bottom borders?
-Dan
Why not define another class for that component and define border-bottom for that class and put it as !important
.another_class{
border-bottom: 1px solid #efefef !important;
}
border-bottom: initial; won't give you a border.
Set the second definition to border-bottom: 1px solid #efefef;

All borders or nothing - CSS

Whenever I try to set left and right border for an inline-block element in my code, it won't work unless I set all.
border:2px solid black; /* does work */
border:0 2px solid black; /* doesn't work*/
Any idea?
the relevant part of CSS:
#highlights2{
width:640px;
text-align:left;
}
#highlights2 .highlight{
width:211px;
display:inline-block;
height:100px;
background-color:#0dc1d0;
}
#centerhighlight{
border:0 2px solid rgba(0,0,0,0.5);
border:2px solid black;
}
and HTML:
<div id="highlights2"><div class="highlight">asd</div><div style="" class="highlight" id="centerhighlight">fgh</div><div class="highlight">jkl</div></div>
This syntax is not valid for defining borders. If you want different styles for vertical and horizontal borders you need to write it longhand, for example:
border: 2px solid black;
border-top-width: 0;
border-bottom-width: 0;
If you want to use the shorthand for border width, you can use this:
border-width:0 2px;
border-style: solid;
border-color: black;
jsFiddle

Shifting the border-left to border-right CSS

Hi I have a CSS code with the following style property.
.spotlight{
border-left: 21px solid #ffb80d;
}
I need to move the spotlight to right for RTL changes.I need to add a change like
.locale-right-to-left .spotlight {
border-right: 21px solid #ffb80d;
}
But if I make this change there will be 2 spotlights on both sides of the text. Is there a way where I can ignore the border-left property ?
.locale-right-to-left .spotlight {
border-right: 21px solid #ffb80d;
border-left: 0;
}
If you use :
element {
direction:rtl;
}
then draw your border from a pseudo-element:
element {
direction:rtl;
}
element .spotlight{
position:relative;
}
element .spotlight:before {
position:absolute;
left:auto; /* no need*/
right:auto; /* no need*/
top:0;
bottom:0;
border-left: 21px solid #ffb80d;/* or border-right */
}
The position of :before will relay on direction
Define border-left 0
.locale-right-to-left .spotlight
{
border-right: 21px solid #ffb80d;
border-left: 0;
}

CSS hover border makes elements adjust slightly

I have an unordered list full or anchors. I have a CSS :Hover event that adds borders to it but all the anchors to the left slightly adjust when i hover because it is adding 1px to the width and auto adjusting. how do i make sure the positioning is absolute?
div a:visited, #homeheader a{
text-decoration:none;
color:black;
margin-right:5px;
}
div a:hover{
background-color:#D0DDF2;
border-radius:5px;
border:1px solid #102447;
}
div li{
padding:0;
margin:0px 10px;
display:inline;
font-size:1em;
}
<div>
<ul>
<li>this</li>
<li>that</li>
<li>this again</li>
<li>that again</li>
</ul>
</div>
I made a JS Fiddle demo here.
You can add a transparent border to the non-hover state to avoid the "jumpiness" when the border appears:
http://jsfiddle.net/TEUhM/3/
#homeheader a:visited, #homeheader a{
border:1px solid transparent;
}
You can also use outline, which won't affect the width i.e. so no "jump" effect. However,support for a rounded outline may be limited.
You could use a box shadow, rather than a border for this sort of functionality.
This works because your shadow doesn't 'take size in the DOM', and so won't affect the positioning, unlike that of a border.
Try using a declaration like
box-shadow:0 0 1px 1px #102447;
instead of your
border:1px solid #102447;
on your hover state.
Below is a quick demo of this in action:
DEMO
#homeheader a:visited,
#homeheader a {
text-decoration: none;
color: black;
margin-right: 5px;
}
#homeheader a:hover {
background-color: #D0DDF2;
border-radius: 5px;
box-shadow: 0 0 1px #102447;
}
#homeheader li {
padding: 0;
margin: 0px 10px;
display: inline;
font-size: 1em;
}
<div id="homecontainer">
<div id="homeheader">
<ul>
<li>this
</li>
<li>that
</li>
<li>this again
</li>
<li>that again
</li>
</ul>
</div>
</div>
Add a margin of 1px and remove that margin on hover, so it is replaced by the border.
http://jsfiddle.net/TEUhM/4/
After taking a long time pressure i found a cool solution.
Hope that it will help others.
on the add the folloing code :
HTML
<div class="border-test">
<h2> title </h2>
<p> Technology founders churn rate niche market </p>
</div>
CSS
.border-test {
outline: 1px solid red;
border: 5px solid transparent;
}
.border-test:hover {
outline: 0px solid transparent;
border: 5px solid red;
}
Check live : Live Demo
Hope it will help.
No one has mentioned it here, but the best and simplest solution to this in my opinion is to use "box shadow" instead of borders. The magic is on the "inset" value which allows it be like a boarder.
box-shadow: inset 0 -3px 0 0 red;
You can offset the X or Y to change top/bottom and use -negative value for opposite sides.
.button {
width: 200px;
height: 50px;
padding: auto;
background-color: grey;
text-align: center;
}
.button:hover {
box-shadow: inset 0 -3px 0 0 red;
background-color: lightgrey;
}
<div class="button"> Button </div>
You can use box-shadow which does not change your box-size, unlike border.
Here is a little tutorial.
Just add the following code into your css file
#homeheader a {
border:1px solid transparent;
}
The CSS "box-sizing" attribute fixed this problem for me. If you give your element
.class-name {
box-sizing: border-box;
}
Then the width of the border is added to the inside of the box when the browser calculates its width. This way when you turn the border style on and off, the size of the element doesn't change (which is what causes the jittering you observed).
This is a new technology, but the support for border-box is pretty consistent. Here is a demo!
The easiest method I found was using 'outline' instead of 'border'.
#home:hover{
outline:1px solid white;
}
instead of
#home:hover{
border:1px solid white;
}
Works the best!
https://www.kirupa.com/html5/display_an_outline_instead_of_a_border_hover.htm
Add a negative margin on hover to compensate:
#homeheader a:hover{
border: 1px solid #102447;
margin: -1px;
}
updated fiddle
In the fiddle the margin: -1px; is a little more complex because there was a margin-right getting overridden, but it's still just a matter of subtracting the newly-occupied space.
I too was facing the same problem. The fix mentioned by Wesley Murch works! i.e. adding a transparent border around the element to be hovered.
I had a ul on which :hover was added to every li. Every time, I hovered on each list item, the elements contained inside li too moved.
Here is the relevant code:
html
<ul>
<li class="connectionsListItem" id="connectionsListItem-0">
<div class="listItemContentDiv" id="listItemContentDiv-0">
<span class="connectionIconSpan"></span>
<div class="connectListAnchorDiv">
Test1
</div>
</div>
</li>
</ul>
css
.listItemContentDiv
{
display: inline-block;
padding: 8px;
right: 0;
text-align: left;
text-decoration: none;
text-indent: 0;
}
.connectionIconSpan
{
background-image: url("../images/connection4.png");
background-position: 100% 50%;
background-repeat: no-repeat;
cursor: pointer;
padding-right: 0;
background-color: transparent;
border: medium none;
clear: both;
float: left;
height: 32px;
width: 32px;
}
.connectListAnchorDiv
{
float: right;
margin-top: 4px;
}
The hover defn on each list item:
.connectionsListItem:hover
{
background-color: #F0F0F0;
background-image: linear-gradient(#E7E7E7, #E7E7E7 38%, #D7D7D7);
box-shadow: none;
text-shadow: none;
border-radius: 10px 10px 10px 10px;
border-color: #AAAAAA;
border-style: solid;
}
The above code used to make the containing elements shift, whenever I hovered over connectionsListItem. The fix was this added to the css as:
.connectionsListItem
{
border:1px solid transparent;
}
Use :before to create the border, that way it won't modify the actual content and gives you more freedom. Check it out here:
http://codepen.io/jorgenrique/pen/JGqOMb
<div class='border'>Border</div>
<div class='before'>Before</div>
div{
width:300px;
height:100px;
text-align:center;
margin:1rem;
position:relative;
display:flex;
justify-content:center;
align-items: center;
background-color:#eee;
}
.border{
border-left:10px solid deepPink;
}
.before{
&:before{
content:"";
position:absolute;
background-color:deepPink;
width:10px;
height:100%;
left:0;
top:0;
}
&:hover{
background-color:#ccc;
&:before{
width:0px;
transition:0.2s;
}
}
}
Be careful if you also use padding.
In my case, I had a 5px padding inside the hover defn. It should be moved inside the actual class of the element you want to hover over.
Code snippet

Resources