I would like to make a button in the form of a signpost (rectangle with tip).
_______
| \
|_______/
I want to dynamically write text into the sign, each with different lengths.
If I try this only with a graphic as background graphic, the arrowhead is scaled with and compressed / stretched accordingly.
Therefore the approach to put the text in a normal div and attach the arrowhead as SVG using CSS :after.
The arrow should be fully filled, i.e. I don't have to deal with frame problems. (To increase the visibility I left the SVG black)
My first problem is that the arrowhead is always in the block instead of behind it. this I solved with position:absolute;. But further fine tuning fails, because I can't position based on the end of the block with left: and right:
Questions:
How do I have to position so that the triangle always connects exactly to the end of the box. (no white betwwen)
How can I scale the SVG with the size (height) of the box. (So that the edges fits) (maybe also with consideration of the paddings of the )
Or am I completely on the wrong track with the approach via :after and should rather append the arrow (as SVG file) direkt in the HTML behind the text (text ay enclose with ) and enclose all with the ? But actually I wanted to avoid that, the insert via CSS would be nicer. But if that is the more useful way, I can live with it.
.querverweis{
background-color: #005000;
color: #ffffff;
display: inline-block;
margin: 10px
margin-left: -10px
}
.querverweis:after {
content: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' width='32' height='40' viewBox='0 0 66 100' xml:space='preserve'%3E%3Cpath d='M0 0 L66 50 L0 100 L0 0' style='fill=rgb(0,0,0)'/%3E%3C/svg%3E%0A");
position: absolute;
}
<div class="querverweis">Test</div>
As A Haworth mentions, clip-path might be simpler. To do this, add some padding to the right of the button to always have space where the arrow will live and then clip-path the whole element
.querverweis {
position: relative;
background-color: #005000;
color: #ffffff;
display: inline-block;
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
clip-path: polygon(0% 0%, calc(100% - 1rem) 0, 100% 50%, calc(100% - 1rem) 100%, 0% 100%);
}
<div class="querverweis">Test</div>
<br>
<br>
<div class="querverweis">Test with more text</div>
<br>
<br>
<div class="querverweis" style="max-width:6rem">Test with multi-line text</div>
Related
I have created pie chart like this using HTML and css
I tried Below Code -
HTML -
<div class="pie-chart"></div>
CSS -
.pie-chart {
margin-left: 10px;
--size: 8rem;
--fg: #369;
--bg: #def;
width: var(--size);
height: var(--size);
border-radius: 50%;
display: grid;
place-items: center;
background:
radial-gradient(closest-side, white 40%, transparent 0 99.9%, white 0),
conic-gradient(
#301B84 0 45%,
#715fa5 45% 65%,
#aca6cd 65% 75%,
#d6d0e4 75% 100%);
color: var(--fg);
}
Expecting It should look like below pie chart (inner white border want to create it)-
Note - jQuery, Javascript is not allow for this (only html and css is allowed)
can someone help me with this.?
Conic gradients work in angled slices. If you were to add white gaps in the gradient between each section it would be thinner in the center and wider at the edge. That's likely not what you're looking for.
So, there are two potential solutions.
Solution 1: Use SVG. It was made for this kind of thing. That should still fall into your HTML and CSS only requirement, since SVG is valid HTML. There are tons of generators and tutorials out there.
Solution 2: Add some divider elements into to your chart. This is a bit of a hacky solution, but it works. Here's an example: https://codepen.io/davidleininger/pen/abKJOOo/699fb1595f469e69054e36b27280344a
Basically, you'd update your HTML to include dividers and give them a CSS custom property. Then you use those custom properties to generate divider lines in your chart:
<div class="pie-chart">
<div class="divider" style="--precent: 45;"></div>
<div class="divider" style="--precent: 65;"></div>
<div class="divider" style="--precent: 75;"></div>
<div class="divider" style="--precent: 100;"></div>
</div>
After adding the dividers to your HTML, add this to your CSS, and you've got yourself some divider lines:
.pie-chart .divider {
background: white;
height: 50%;
left: 50%;
margin-left: -1px;
position: absolute;
top: 0;
transform-origin: 0 100%;
transform: rotate(calc(1turn * (var(--precent) / 100)));
width: 2px;
}
The transform is doing the heavy lifting here. It's calculating the position of all of the divider lines and rotating them to the correct position.
I currently have a polygon with text inside shown below
.title {
clip-path: polygon(1% 0, 100% 15%, 96% 90%, 0 75%);
background-color: blue;
color: #FFF;
font-size: 1.7em;
line-height: 50px;
height: 60px;
width: 250px;
}
<h1 class="title"> WELCOME TO</h1>
I am looking for a more browser friendly version of this so I've been looking into using an SVG image. I'm struggling to nicely code this, as you see below I have the SVG shape, after a bit of testing, I quickly realised it doesn't scale well with the browser width. I would be happy if I could just keep it the same size all the time.
Then for the text after researching I learnt about the tag inside an tag, but even that I'm struggling to format the text.
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 7 9" version="1">
<polygon points=".1 0,5 .2,4.4 1.8,0 1.6" style="fill: #253234;" />
<text x="1" y="1" fill="white" style="font-family:arial; font-size:.4">WELCOME TO</text>
</svg>
Does anyone know of a better way of doing this, that works on major browsers and devices?
if i were you i would try to achieve the same effect with only css using rotation for the container, inverting the text rotation with the same amount, then using a pseudo element (:after) with absolute positioning to achieve the non rectangular shape effect.
run the snippet for an example that you can adjust to fit your needs.
.container {
transform:rotate(3deg);
display:inline-block;
position:relative;
top:50px;
padding:20px 30px 20px 20px;
background-color:blue;
}
.container:after {
content:'';
display:block;
background:white;
width:20px;
height:110%;
position:absolute;
top:0;
right:-10px;
transform:rotate(10deg);
}
.title {
color:#fff;
display:inline-block;
font-size:18pt;
text-transform:uppercase;
font-family:arial;
transform:rotate(-3deg)
}
<div class="container"><span class="title">Welcome to </span></div>
Since the first and second version you gave differ so much, I am not that sure what it is you want to achieve. I'm going mostly with the first one.
The main trick is with the way you use the viewBox attribute (and its accompaining preserveAspectRatio). Think of the viewBox as a rectangle that is fit into the area you define with width and height. (here, spelled out in CSS.) The preserveAspectRatio describes the fitting rule: choose the largest possible size for the rectangle that fits inside the element, and move it to the left and vertically to the middle.
Everything inside the <svg> now will remain fixed in position and proportion to that rectangle. If you raise the height of the element, the size of the text will grow; and if you lower its width, eventually it will shrink, but always together with the polygon.
I've positioned the text with text-anchor: middle, which is the equivalent of text-align: center for SVG. Using a font size of 0.4 as you did is not a good idea; browsers are prone to handle values below 1 incorrect.
Finally, if you are using this in place of a <h1> tag, you should either surround it with that to retain accessability, or set appropriate ARIA attributes as shown:
.title {
height: 60px;
width: 100%;
display: block; /* not needed if surrounded by <h1> */
}
.title polygon {
fill: blue;
}
.title text {
font-family: Arial;
font-size: 24px;
fill: #FFF;
text-anchor: middle;
}
<svg class="title" viewBox="0 0 250 60" preserveAspectRatio="xMinYMid meet"
aria-role="heading" aria-level="1">
<polygon points="2.5,0 250,9 240,54 0 45" />
<text x="125" y="36">WELCOME TO</text>
</svg>
Hi I am trying to make the quote box transparent and larger the text size.
Original code below.
<div class="quote"><h1>WOW YOUR AUDIENCE<br></h1><hr style="margin: 0 20%;">
You have not mentioned how much transparency and font size you need so I have taken it randomly. Also you were missing a closing div tag.
Here is the code:
<div class="quote" style="opacity:0.5"><h1 style="font-size:50px">WOW YOUR AUDIENCE<br></h1></div><hr style="margin: 0 20%;">
You have asked to make the complete quote box transparent and not only its background-color(which is white!!). Hopefully this is what you need.
To achieve this without affecting the transparency of the text while making the background-color of the div that surrounds it transparent, use rgba colors instead of opacity
The first 3 values are the Red, Green Blue levels, and the 4th number is the transparency on a scale of 0-1.
Learn more about rgba in css here.
To increase the size of any font, you can use font-size. I used em in this example since it is relative to the screen size but you can use any of the CSS measurement units.
.quote {
background: rgba(200, 54, 54, 0.5);
z-index: 22;
}
h1 { font-size: 6em; }
.example {
position: absolute;
background-color: blue;
top: 10px;
left: 80%;
height: 200px;
width: 50px;
z-index: -1;
}
<div class="quote"><h1>WOW YOUR AUDIENCE<br></h1><hr style="margin: 0 20%;"></div>
<div class="example"></div>
To apply transparency to all elements in a div or to an element itself, you can simply use the opacity style from a range of 0-1 like so: opacity: 0.7;
I've a trapezoid shapes in CSS, but the problem is that I also need the same kind of trapezoid turning the borders opposite, the first trapezoid css is something like this:
#trapezoid1 {
height: 0;
width: 350px;
border-bottom: 190px solid rgb(2, 145, 178);
border-left: 45px solid transparent;
border-right: 45px solid transparent;
padding: 0 8px 0 0;
display:block;
position:relative;
}
But I also need the second trapezoid turning the border-bottom to border-top, however in that case, the text is being flew away from the actual trapezoid.
I did border-top instead of border-bottom to turn the trapezoid opposite.
Here's the full display of the problem.. jsfiddle
Your best option is to use pseudo elements so you dont have to use absolute positioning on the text element.
Using both :before and :after will help create the desired shape. The borders are also transparent so you don't have to worry about background images being coloured over.
#trapezoid {
width: 260px;
height: 190px;
background: red;
margin-left: 45px;
position: relative;
}
#trapezoid:before {
content: '';
border-right: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
left: -45px;
top: 0;
}
#trapezoid:after {
content: '';
border-left: 45px solid red;
border-bottom: 190px solid transparent;
position: absolute;
right: -45px;
top: 0;
}
<div id="trapezoid">
Text in here
</div>
You can also refer to one of my previews answers which give a good overview at all of the different possible ways of creating a CSS trapezoid.
Responsive CSS Trapezoid Shape
How about this:
HTML (add span tags around trap2 text)
<div id="trapezoid1">
Designing Something
</div>
<br/>
<div id="trapezoid2">
<span id="trap2-text">Designing Opposite</span><!-- NEW -->
<!-- I need the text in proper place which currently isn't -->
</div>
CSS (add one rule)
#trap2-text {
position: absolute;
top: -190px;
left: -25px;
}
DEMO
I generally like pure css shapes, but I thought SVG might make your life easier in this case so I started fiddling around with your fiddle. I'm not completely satisfied with the results but it gives some advantage like dynamic size.
Fiddle with comments: http://jsfiddle.net/bo5k36pa/8/
If you want to use this solution I highly recommend to encode your inline svgs in base64 to avoid compability and encoding problems. See this answer for details.
Explanation
The idea was to use an inline svg as background image, so it will stretch to containers of any size.
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 2" preserveAspectRatio="none"><path style="fill: rgb(2, 145, 178);" d="M 0.5 0 L 3.5 0 L 4 2 L 0 2 Z" /></svg>');
background-size: 100%;
The path that makes up the trapez could be modified, if different angles or shapes are required, it could even be generated dynamically using javascript. But the real bummer here is, we can't style inline svg background images. Meaning for example to change just the fill color we have to define the entire svg markup again.
Possible solutions to avoid multiple inline svgs
Use <use>. You can define <symbols> in an external svg file and reference them in an inline <svg> via their id attributes. And we can still style those symbols using CSS. However, it would require a fair amount of extra markup in every container. Something like this:
<svg viewBox="0 0 4 2" role="img" title="Trapez"><use xlink:href="path/to/images/shapes.svg#trapez"></use></svg>
Use CSS filters to change appearance. Example fiddle / Browser Support
Go back to CSS Shapes. I'd recommend to take advantage of :before and :after pseudo elements to keep such fancy appendages a bit separate from your content box.
I have a division that has a background image but it needs to be a varible size. I'm using three images. One of the top, one for the bottom and a repeating one for the middle.
I've only got one div to work with and given the middle background image to that and then used the before and after pesudo classes to place the other images. The image from the main division shows up behind these two since they are semi transparent. Is there a way round this in css or a better method to do it?
HHTML:
<div class="faq">
<strong>Q. Who was the greatest business man?</strong><br />
<p><strong>A. </strong>Noah. He kept his stock afloat, while the rest of the world went into liquidation.</p><br />
<strong>Q. How should my employees let off steam?</strong><br />
<p><strong>A. </strong>Take them see to see the comedian Sampson. He'll bring the house down.</p><br />
</div>
CSS - style
.faq{
background: transparent url(../images/image_middle.png) repeat-y center;
color: #ffffff;
display: block;
}
.faq:before {
background: transparent url(../images/image_top.png) no-repeat center top !important;
}
.faq:after {
background: transparent url(../images/image_bottom.png) no-repeat center bottom !important;
}
CSS - layout
.faq:before {
padding-top: 20px;
display: block;
content: "\A";
}
.faq:after {
padding-top: 14px;
display: block;
content: "\A";
}
.faq{
margin: 20px 0 5px !important;
padding: 0 20px 0 15px !important;
}
The best way to do this is by using multiple backgrounds - see https://developer.mozilla.org/en-US/docs/CSS/Using_CSS_multiple_backgrounds. in this way, you can specify the 3 different images and their positions as styles for the element. List the top image first.
If your browser support requirements won't work with CSS multiple backgrounds, you can get the same result by styling other elements - such as a h1 or p:last inside your div. This approach is more complicated, since you have to be very careful about the position of elements inside that div.
Note that a background or image will always show through transparent areas of an image above it. If you don't want this, you must put something opaque into that cover-up image - such as the background color that you're trying to fade to.
For more detailed help, please post a self contained example of the code you're working with.