styling the outline border with outer overflow set to hidden - html

The CSS style:
.outer {
position: relative;
width: 100%;
height: 200px;
background-color: #000;
overflow: hidden;
}
.outer:focus {
outline: 10px solid #00FF00;
}
.inner {
position: absolute;
width: 50%;
height: 200px;
background-color: #F0F;
left: 50%;
}
.inner:focus {
outline: 10px solid #FFFF00;
}
The HTML code:
<div tabindex="0" class="outer">
<div tabindex="0" class="inner">
The problem:
I want to make inner div focusable with an outline border, but because of overflow: hidden; I can't do it. This is only an example. Also, I don't wanna touch the overflow: hidden of the outer div when the focus is on the inner one, so this won't go. Perhaps there's an easy way(code only, no imgs-graphics) to implement some sort of border on the focusable element?
*CSS-HTML code only pls. No JS

Use a negative offset for the outline when the div is focused, like so:
.inner:focus {
outline-offset: -10px;
}
The value should be equal to the outline-width.
As an alternative approach you might also use an inset box-shadow e.g.
box-shadow: inset 0 0 0 10px #ff0;

you can use ::after property
.inner:focus::after {
content: "";
height: 90%;
outline: 10px solid #ffff00;
position: absolute;
top: 10px;
width: 98.1%;
z-index: 99999;
}

You could use border instead of outline and set box-sizing: border-box
.outer {
position: relative;
width: 100%;
height: 200px;
background-color: #000;
overflow: hidden;
}
.outer:focus {
outline: 10px solid #00FF00;
}
.inner {
position: absolute;
width: 50%;
height: 200px;
box-sizing: border-box;
background-color: #F0F;
left: 50%;
}
.inner:focus {
border: 10px solid #FFFF00;
}
<div tabindex="0" class="outer">
<div tabindex="0" class="inner">

You can use either box-shadow: inset or outline with negative outline-offset
.inner:focus::after {
content: '';
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* #1 */
box-shadow: inset 0 0 0 4px blue;
/* #2 */
outline: 4px;
outline-offset: -4px;
}

Related

CSS: How to overlap circle element properly

What I want to do is to cover circle element with square. But I can still see circle border.
When I inspect the element, the child element size doesn't include the parent's border (118px x 118px) so I tried to remove box-sizing: border-box;. Even though child element size is 120px x 120px, the same thing still happens.
How can I cover the circle properly?
.circle {
position: relative;
width: 120px;
height: 120px;
border-radius: 50%;
border: 1px solid red;
box-sizing: border-box;
background-color: white;
}
.square {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
}
/* added by editor for betetr visualization purpose */
body {
background: gray;
}
<div class="circle">
<div class="square"></div>
</div>
The content itself starts within the border, not at the end of the border. As such you have to position the element out of the content area. Instead of using top, right, bottom, left you could simply use inset:
.circle {
position: relative;
width: 120px;
height: 120px;
border-radius: 50%;
border: 1px solid red;
box-sizing: border-box;
background-color: white;
}
.square {
position: absolute;
inset: -1px;
background-color: white;
}
/* added by editor for betetr visualization purpose */
body {
background: gray;
}
<div class="circle">
<div class="square"></div>
</div>
You can cover the circle properly by adding a border also to the square. and moving it a bit.
.circle {
position: relative;
width: 120px;
height: 120px;
border-radius: 50%;
border: 1px solid red;
box-sizing: border-box;
background-color: white;
}
.square {
position: absolute;
top: -1px;
left: -1px;
width: 100%;
height: 100%;
background-color: rgba(255,255,255,0.5);
border: 1px solid white;
}
/* added by editor for betetr visualization purpose */
body {
background: gray;
}
<div class="circle">
<div class="square"></div>
</div>

Issue with inset Box-Shadow and Transform: Scale() on Chrome

I need to use inset Box-Shadow to simulate border, because I need to control how horizontal/vertical borders overlap if they have different colors.
Here I have a Top border only. However, Scale() and certain offsets causes a right/left borders to appear.
This happens on Chrome, but not IE or Edge.
Screenshot
I understand this is related to sub-pixels. Is there a mitigation?
Again, CSS border is not an option for me.
.element {
position: absolute;
left: 22px;
top: 20px;
width: 100px;
height: 100px;
background: yellow;
box-shadow: inset 0 1px 0 0 red;
padding: 5px;
box-sizing: border-box;
}
.container {
background: white;
transform: scale(1.2);
width: 200px;
height: 200px;
}
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="element">ABCD</div>
</div>
</body>
</html>
Thanks!
If you can't use a border on your .element, then why not create a pseudo-element to apply the border to? A transform: scale() would not change anything about how it looks.
*,
*::before {
box-sizing: border-box;
}
.container {
background: white;
transform: scale(1.2);
width: 200px;
height: 200px;
}
.element {
position: absolute;
left: 22px;
top: 20px;
width: 100px;
height: 100px;
background: yellow;
padding: 5px;
}
.element::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-top: 1px solid red;
}
<div class="container">
<div class="element">ABCD</div>
</div>

Display Pseudo element above parent when parent's overflown is hidden

div {
margin: 50px;
position: relative;
background-color: red;
width: 200px;
height: 50px;
border: 2px solid black;
}
div::after {
content: '';
position: absolute;
background-color: green;
width: 100px;
height: 100px;
border-radius: 100%;
top: -25px;
left:50px;
border: 2px solid black;
}
div.overflow-hidden {
overflow: hidden;
}
<div>1st</div>
<div class="overflow-hidden">2nd</div>
1st case: as expected.
2nd case[overflow-hidden]: Middle part of top and bottom border should be green. Looks like circle is not above its parent div's border. Is there any way to make it above it? Whats happening here? Will the z-index work?
Why is this happening?
This is because overflow: hidden; clips the content to the content box.
hidden
Content is clipped if necessary to fit the content box. No scrollbars
are provided.
MDN Web docs - https://developer.mozilla.org/en/docs/Web/CSS/overflow
This can be seen in the first example below as I have changed the border to be transparent.
What can you do?
One way to get around this would be to apply the border using an absolutely positioned pseudo element instead of to the containing div.
div {
background-color: red;
height: 50px;
margin: 50px;
overflow: hidden;
position: relative;
width: 200px;
}
div::after {
background-color: green;
border: 2px solid black;
border-radius: 100%;
content: '';
height: 100px;
left: 50px;
position: absolute;
top: -25px;
width: 100px;
}
div.overflow-with-border {
border: 2px solid transparent;
}
div.overflow-with-pseudo {
padding: 2px;
}
div.overflow-with-pseudo::before {
border: 2px solid black;
box-sizing: border-box;
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
<div class="overflow-with-border">1st</div>
<div class="overflow-with-pseudo">2nd</div>

Don't work border when you hover DIV

I need when you hover a mouse on one div other div with parametres appear from below and these both divs have common border.
Now I have border only on first div. It looks like first div don't contain second, but in html code div with parametres is beetwen of first.
What is wrong?
.item {
width: 220px;
height: 300px;
margin: 10px 3px;
float: left;
position: relative;
}
.item:hover .item_inner {
position: absolute;
top: 0;
left: 0;
z-index: 10;
background: #fff;
box-shadow: 0 1px 14px rgba(0,0,0,0.3);
height: 100%;
}
.item_param {
display: none;
text-align: left;
padding: 0 5px;
margin: 10px 0;
background-color: #f3f3f3;
}
.item_inner{
width: 100%;
height: 100%;
position: relative;
padding-bottom: 5px;
border: 1px solid green;
}
.item_inner:hover .item_param {
display: block;
top: 100%;
width: 100%;
position: absolute;
}
<div class="item">
<div class="item_inner">
TEXT
<div class="item_param">
<p>Parametres</p>
<p>Parametres</p>
<p>Parametres</p>
</div>
</div>
</div>
.item_inner:hover .item_param {
display: block;
top: 100%;
width: 100%;
position: relative;
}

Moving CSS content onto a border

Right, I ran into a bit of a problem and not to sure if this can be solved another way.
I need to move the content: "F"; and center it onto the border I have in the top left corner. Now is this possible without creating another element?
HTML:
<div class="userBoxF"></div>
CSS:
.userBoxF {
width: 200px;
height: 200px;
background: #eee;
border: 1px solid;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.userBoxF:after {
content: "F";
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border: 40px solid #F385FF;
border-right-color: transparent;
border-bottom-color: transparent;
font-size: 30px;
}
The only way I can think to do it is to create the corner as a completely separate element so I can put the text "F" into a span (or something) and move it that way.
Demo Here
Note: Nothing here will change size, width and height for both the box and corner will always be the same.
Here is what I want, using the solution i found but would rather not use.
HTML:
<div class="userBoxF">
<div class="corner"><span>F</span></div>
</div>
CSS:
.userBoxF {
width: 200px;
height: 200px;
background: #eee;
border: 1px solid;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.userBoxF .corner {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border: 40px solid #F385FF;
border-right-color: transparent;
border-bottom-color: transparent;
font-size: 30px;
}
.userBoxF .corner span {
display: block;
position: absolute;
top: -30px;
left: -20px;
}
Here is a demo of the solution I came up with but I would rather not create anymore elements.
My Solution
You can use :before wit :after together.
I removed the span:
<div class="userBoxF">
</div>
And changed the CSS blocks to this:
.userBoxF:before {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border: 40px solid #F385FF;
border-right-color: transparent;
border-bottom-color: transparent;
content: "";
}
.userBoxF:after {
display: block;
position: absolute;
top: 10px;
left: 14px;
content: "F";
font-size: 30px;
}
And here's the updated fiddle
EDIT: Here's an added bonus!
You can jack the "F" from the class, if you want it to be more versatile, if you use CSS's attr inside content. Example:
<div class="userBox" data-l="F">
</div>
And:
.userBox:after {
display: block;
position: absolute;
top: 10px;
left: 14px;
content: "" attr(data-l);
font-size: 30px;
}
And another fiddle
Arguably the "F" is actual content as it's not a styling option...it actually denotes something and, perhaps should be read by a screenreader (for instance) then a span with a gradient (TL - BR) mightbe more appropriate.
JSFiddle Demo
HTML
<div class="userBoxF">
<span class="section-letter">F</span>
</div>
CSS
.userBoxF {
width: 200px;
height: 200px;
background: #eee;
border: 1px solid;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.section-letter {
position: absolute;
top: 0;
left: 0;
width:2em;
height:2em;
line-height: 1em;
text-align: left;
padding:0.25em 0 0 0.25em;
font-size: 30px;
background: linear-gradient(135deg, pink 0%, pink 50%, transparent 50%, transparent 100%);
}
Simply use another :psuedo:
Demo Fiddle
.userBoxF {
width: 200px;
height: 200px;
background: #eee;
border: 1px solid;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.userBoxF:before,.userBoxF:after{
position: absolute;
top: 0;
left: 0;
}
.userBoxF:before {
content:"";
border: 40px solid #F385FF;
border-right-color: transparent;
border-bottom-color: transparent;
}
.userBoxF:after {
content:attr(data-l);
top: 10px;
left: 10px;
font-size: 30px;
}
From a single pseudo, you can use a gradient as background : DEMO
.userBoxF {
width: 200px;
height: 200px;
background: #eee;
border: 1px solid;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.userBoxF:after {
content:"F";
position: absolute;
top: 0;
left: 0;
text-indent:20px;
line-height:60px;
width:80px;
height:80px;
background:linear-gradient(to bottom right, #F385FF 51%, transparent 49%);
font-size: 30px;
}
background-image as gradient can be just an image like in old days :
DEMO: