Avoiding border radius with text in span - html

I have an editable span with rounded corners as shown in the picture below. As you can see, the text runs off the corner and I would love a way to keep the text inside the box. is there a good way to do this? I don't want to add padding that goes all the way down the sides or across the top, I really just want to avoid the corners with border-radii. Here is a JSFiddle demonstrating the current state.
Thanks!
Current CSS:
#container {
box-sizing: border-box;
position: absolute;
transition: border 0.2s;
border: 2px solid rgba(128, 223, 255, 0);
border-radius: 7px;
display: table-row;
height: 200px;
width: 300px;
}
.typeSpace {
background-color: green;
display: inline;
position: absolute;
bottom: 0;
text-align:center;
white-space: nowrap;
left: 10px;
right: 10px;
overflow: auto;
-ms-overflow-style: none;
overflow-y: hidden;
text-align: left;
}
#borderText {
left: 0;
right: 0;
bottom: 0;
top: 0;
font-size: 17px);
white-space: normal;
line-height: 15px);
border-radius: 20px 20px 0 0;
}

So what you want this to look like, is something like this? _ representing automatic "spacing".
_XX XXX X_
XXX XXX XX
X XXXX XXX
This could be done by inserting two elements into the span before the text, and then floating one to the left, and one to the right.
Only, your span is editable here (was that supposed to be contenteditable, or are you using some other mechanism? Either way, shouldn't matter) - so those would be likely to be removed by the user, when they modify the text content.
Okay, pseudo elements to the rescue! But wait, only ::before would actually come before the text, ::after would come behind it - and behind doesn't do us any good, when it comes to floating.
But we can use the ::before pseudo element to generate the space on the right - and use text-indent for that on the left.
#container {
box-sizing: border-box;
position: absolute;
transition: border 0.2s;
border: 2px solid rgba(128, 223, 255, 0);
border-radius: calc(var(--scale)*7px);
display: table-row;
height: 200px;
width: 300px;
}
.typeSpace {
background-color: green;
display: inline;
position: absolute;
bottom: 0;
text-align: center;
white-space: nowrap;
left: calc(var(--scale) * 10px);
right: calc(var(--scale) * 10px);
overflow: auto;
-ms-overflow-style: none;
overflow-y: hidden;
text-align: left;
text-indent: 1em; /* provides the spacing on the left */
}
#borderText {
left: 0;
right: 0;
bottom: 0;
top: 0;
font-size: calc(var(--scale) * 17px);
white-space: normal;
line-height: calc(var(--scale) * 15px);
border-radius: 20px 20px 0 0;
}
/* provides the spacing on the right */
.typeSpace::before {
content: "";
float: right;
width: 1em;
}
<div id="container">
<span class="typeSpace" id="borderText" editable>I wish I could see the corners of this text right here</span>
</div>
Of course this will only work for the top corners - if you needed the same thing at the bottom, this method won't do.
Using CSS Shapes would probably be another way to do it - but this one here is easier, I think.

Related

Make element with position: absolute stretch the shadow of parent?

I have a usual search as most websites do. The results are shown below on the div that is visually connected to the search input.
It looks like this:
I need to have one solid shadow for the div parent but can't figure out or find online the way to do this.
I thought that I could either make 2 separate shadows, but that will look inconsistent and just terrible. Or I could make a div below with the same height and width that will act as a shadow but that's a non-necessary complication + the .search-results div's height will change dynamically.
This is an example:
body {
background-color: gray;
}
.search-wrapper {
position: relative;
margin: 100px 100px 0px 100px;
width: 200px;
overflow: initial;
box-shadow: 0px 0px 10px 10px rgba(0,0,0,0.3);
}
.search {
width: 200px;
height: 30px;
color: white;
border-radius: 4px;
} .search input {
padding: 0;
background-color: #022222;
border: none;
height: 100%;
width: 100%;
color: white;
}
.search-results {
position: absolute;
height: 150px;
width: 200px;
background-color: black;
}
<div class="search-wrapper">
<div class="search">
<input placeholder="air max . . .">
</div>
<div class="search-results">
</div>
</div>
I am sure there must be a clever and simple way to do this.
Please help,
Thank you
You don't need to use positions here and you can use FlexBox instead. It's the best way and a lot easier. Also, you can ignore all of them, they will place on top of each other because they are block-level tags/elements. (divs)
You don't need to put the input in another div parent, use it as I did.
Sorry, I couldn't understand your code, so I must write the whole code from the beginning.
EDIT
I removed display flex, cause it's not necessary.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: Arial;
border-radius: 10px;
background-color: #fff
}
body {
height: 100vh;
background-color: gray;
padding: 30px
}
.search-wrapper {
/* EDITED HERE ADDED HEIGHT */
position: relative;
z-index: 999;
width: 200px;
height: 160px;
box-shadow: 0 0 2px 5px rgba(232, 232, 232, .2)
}
.search-input {
width: 100%;
position: absolute;
padding-block: 5px;
border: none;
outline: none;
padding: 15px
}
.search-result {
/* EDITED HERE */
position: absolute;
z-index: 999;
bottom: 0;
width: 100%;
padding: .5px
}
p {
padding: 10px 0 10px 10px;
}
p:hover {
background-color: #e8e8e8;
cursor: pointer
}
<div class='search-wrapper'>
<input class='search-input' placeholder='Search...'>
<div class='search-result'>
<p>Nike Airforce</p>
<p>Nike Airforce</p>
<p>Nike Airforce</p>
</div>
</div>

Is there a CSS solution for this design?

Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().

How could I make a trapezius div

How could I make the effect of below picture with HTML, CSS using the the bootstrap framework?
I need two adjacent divs with trapezoid shape (or separated by a diagonal line). Both need to have a border.
You can do this by drawing a shape in CSS.
You can draw such a triangle in CSS by playing with different borders (top, right, bottom left) of an element that has zero width.
Example: https://css-tricks.com/snippets/css/css-triangle/
In the example below I use the pseudo element :after for this effect:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
padding-left: 10px;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
/* The triangle will be position:absolute, so it requires a `position:relative` parent */
position: relative;
/* We are drawing a full rectangle later, so we hide the rest of it */
overflow: hidden;
}
.container div:last-child {
background: #ff6666;
}
.container div:first-child:after {
position: absolute;
display: block;
content: ' ';
padding: inherit;
box-sizing: border-box;
/* Change below units (you can use px not just em)
to make the line become at different angles */
border-top: 1.3em solid transparent;
border-bottom: 1.3em solid transparent;
border-right: 1.3em solid #ff6666;
right: 0;
top: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
Update
But as you indicated in the comment, you wanted a different answer that uses div2 for the triangle, so here you are:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
padding-left: 10px;
}
.container div:last-child {
background: #ff6666;
position: relative;
padding-left: 1.3em;
}
.container div:last-child:before {
position: absolute;
content: '';.
width: 0;
height: 0;
box-sizing: border-box;
/* Change below units (you can use px not just em)
to make the line become at different angles */
border-top: 1.3em solid #66ff66;
border-bottom: 1.3em solid transparent;
border-right: 1.3em solid transparent;
top: 0;
left: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
Update 2
The picture you showed in comments also included real borders. This requires changing the approach. The new approach still uses :before, but adds border to it, and rotates it 45 degrees.
The idea is based on an example from: https://kilianvalkhof.com/2017/design/sloped-edges-with-consistent-angle-in-css/
To imagine it:
Here's the code:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
padding-left: 10px;
border: 1px solid;
border-right: none;
}
/*
The following assumes diemnsions 1.3em * 1.3em
Your real case can change the number
*/
.container div:last-child {
background: #ff6666;
position: relative;
border: 1px solid;
border-left: none;
padding-left: calc(1.5 * 1.3em);
overflow: hidden;
}
.container div:last-child:before {
position: absolute;
content: '';
width: calc(2 * 1.3em);
height: calc(2 * 1.3em);
box-sizing: border-box;
background: #66ff66;
border: 1px solid ;
transform:rotate(45deg);
margin-top: -1.3em;
margin-left: -1.3em;
left: 0;
top: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
just use border-right like following code snippet and see result :
.parent{
width: 100%;
display: flex;
background-color: #01579b;
}
.div1 {
width: 30%;
border-bottom: 100px solid #000;
border-right: 50px solid transparent;
}
.div2 {
width: 70%;
height: 100px;
}
<div class="parent">
<div class="div1"></div>
<div class="div2"></div>
</div>

how to create a half-box in html/css

I'm trying to create a div that has a left and top border with text in top line. what I am trying to achieve is the following...
html half box
I am able to get the top with the text using the following css or alternately a table but can't get it with the left border also. any 'outside the box' thinkers?
.hr-sect {
display: flex;
align-items: center;
color: blue;
margin: 8px 0px;
}
.hr-sect::before
{
content: "";
width: 20px;
background: #000;
height: 1px;
font-size: 0px;
line-height: 0px;
margin: 0px 8px;
}
.hr-sect::after {
content: "";
width:100%;
background: #000;
height: 1px;
font-size: 0px;
line-height: 0px;
margin: 0px 8px;
}
CATEGORY
CATEGORY
You can simulate that interrupted border line by using an absolutely placed div that has a non-transparent background, just make sure it matches the actual background color.
.half-box {
border-left: 1px solid black;
border-top: 1px solid black;
position: relative;
padding: 30px;
}
.half-box > .title {
background-color: white;
padding: 0 10px;
position: absolute;
top: 0;
left: 30px;
font-size: 20px;
transform: translateY(-50%);
}
<div style="height: 100px">
</div>
<div class="half-box">
some content
<div class="title">
CONTENT
</div>
</div>
Set a positioning context on the outer box with position: relative;
For the border, use a pseudo ::before element with content: " "; and give it a position: absolute; to take it out of the flow. Give it a top and left border.
For the heading, also use position: absolute; and move it up with top: -20px or whatever. Set the same background color as the outer box to mask the border.
Adjust your margins and paddings as needed.
See this codepen: https://codepen.io/matthewsmith_io/pen/RVYQqy

CSS3: Tooltip Max Width with Word Wrap

Trying to apply max-width in case of text wrap for tooltip in this jsfiddle, but it applies the default width.
HTML:
<div id="container" style="margin: 167px 135px 0px 0px; height: 400px">
<a class="tooltip" tip="television">content1</a>
<a class="tooltip" tip="By noon yesterday, news television screens were filled with visuals of a Delhi we have been familiarized with over the past year.">content2</a>
</div>
CSS:
.tooltip{
display: inline;
position: relative;
white-space: pre-wrap; /* css-3 */
margin: 20px 20px 20px 20px;
height: 30px;
width: 50px
}
.tooltip:hover:after{
background: #8FBC8F;
border-radius: 5px;
bottom: 26px;
color: #000;
content: attr(tip);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
width:auto;
min-width:50px;
max-width:500px;
}
.tooltip:hover:before{
border: solid;
border-color: #8FBC8F transparent;
border-width: 6px 6px 0 6px;
bottom: 20px;
content: "";
left: 50%;
position: absolute;
z-index: 99;
}
when the text in the tooltip is getting word wrapped, width should go up to some max width instead of the default width so that it is convenient for reading.
this jsfiddle works when i put display: inline-table; like below
.tooltip:hover:after{
:
:
display: inline-table;
}
But it works only in Chrome and not on IE
You have to use display:inline and max-width and for some browser use word wrap.There is a good tutorial to create css3 tooltip create css3 tooltip.
Here's some code from that tutorial:
.tooltip
{
display: inline;
position: relative;
}
.tooltip:hover:after
{
background: #333;
background: rgba(0,0,0,.8);
border-radius: 5px;
bottom: 26px;
color: #fff;
content: attr(title);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
width: 220px;
max-width: 220px;
}
Stumbled upon the same problem, and after some fiddling found following workaround for my case: you have to wrap tooltip content in another element, which will have your expected max-width for the tooltip in width, and positioned absolute. Then wrapped content will use this as baseline max width while wrapping text.
Verified that it works in latest public IE/Edge/Chrome/FF at the time of writing
Codepen: https://codepen.io/jfhs/pen/LzbwgJ
In code:
<div class="tooltip">
<div class="tooltip-content-wrapper">
<div class="tooltip-content">Long long text</div>
</div>
</div>
CSS:
.tooltip {
position: relative;
}
.tooltip-content-wrapper {
position: absolute;
width: 100px; /* THIS is your max-width for tooltip */
visibility: hidden;
}
.tooltip:hover .tooltip-content-wrapper {
visibility: visible;
}
.tooltip-content {
display: inline-block;
}
Please change your CSS min-width and max-width like below:
.tooltip:hover:after{
background: #8FBC8F;
border-radius: 5px;
bottom: 26px;
color: #000;
content: attr(tip);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
width:auto;
min-width:500px; /* I have changed here */
max-width:500px;
}
I came across this old question as I too was looking to see if it was possible to get min-width and max-width to work without having to add JavaScript or extra elements (as I was sourcing the tooltip text from an attribute). It turns out that changing width: auto; to width: max-content; in your jsfiddle does the trick (as suggested at: https://stackoverflow.com/a/62853552). Screenshot: