Creating Horizontal Title Bars using Spans - html

I wanted to create a title thats centered within a div with two spans to the left and right of it. I managed to do so but there's two issues I just can't seem to think of a solution for.
The first involves vertically centering the two border spans with
the middle span 'Title'.
The second is having the left border expand all to the left edge of the div and vice versa for the right (obviously the width of the spans would need to be changed from the original).
Using two hrs seemed like a good idea but would it probably involve too much hacking to do something so simple.
HTML
<div id="container">
<div class="title">
<span class="border"></span>
<span>Title</span>
<span class="border"></span>
</div>
</div>
CSS
#container {background: #eee; height: 100px; width: 100%;}
.title {margin: 0 auto; text-align: center; margin-top: 20px;}
.title span:nth-child(2) {padding: 0 10px;}
.border {display: inline-block; width: 40px; background: #000; height: 1px;}

I assume that you want the lines before and after a word, than why not use pseudo elements? You will need single element, no span and no other element to achieve that effect.
Demo
I've made the below example from scratch, here, am using :before and :after pseudo to create virtual elements, and then am positioning them accordingly using position: absolute; which is set to top: 50; for vertical centering, and then am deducting the width of each pseudo element so that it doesn't overlap your word.
div {
margin: 150px;
position: relative;
float: left;
}
div:before,
div:after {
content: "";
width: 50px;
position: absolute;
top: 50%;
height: 1px;
background: #f00;
}
div:before {
left: -50px;
}
div:after {
right: -50px;
}
As you commented, if you want the lines to expand fully from edge to edge.. than wrap the text in a span and make the changes as below in your CSS
Demo 2 (Expands 100%)
<div><span>Hello</span></div>
div {
text-align: center;
position: relative;
}
div span {
background: white;
position: relative;
z-index: 1;
}
div:before {
content: "";
width: 100%;
position: absolute;
top: 50%;
left: 0;
height: 1px;
background: #f00;
z-index: 0;
}

Related

Content background to ignore parent container but text to maintain positioning

So I have a CSS issue that I can't seem to get my head around. I have solved this in a number of ways none of which seem to pass WCAG Axe accessibility tests as it mentions overlapping of elements.
I have some text whose position is correct, but I want the background-color of the text to span the whole width of the page without altering the position of the text.
Here's a simple example of the issue I want to solve.
.container {
display: block;
margin: 0 auto;
width: 50%;
background: grey;
height: 100vh;
}
.content {
width: 100%;
background: green;
}
<div class="container">
<p class="content">this is some text I want this text to be positioned here but the green background to span the whole width </p>
</div>
My solution involved an extra absolute div with the background set, but that didn't pass accessibility. Any pointers would be great, I appreciate I'm probably being silly here.
You can add the following settings to .content: position: relative; and left: -50%; to move its left side to the left border, and a left and right padding of 50% to make it wider/full width of its parent and keep the text contents aligned with the .container element:
html,
body {
margin: 0;
}
.container {
display: block;
margin: 0 auto;
width: 50%;
background: grey;
height: 100vh;
}
.content {
width: 100%;
background: green;
position: relative;
left: -50%;
padding-left: 50%;
padding-right: 50%;
}
<div class="container">
<p class="content">this is some text I want this text to be positioned here but the green background to span the whole width </p>
</div>
Note that the added padding would not work if you somewhere have a box-sizing: border-box rule for all your elements. In this case you'd have to add box-sizing: content-box to the .content rule to reset this parameter to its default.
You can achieve this by so many ways, here I have used ::before pseudo element and without setting it's width apply left:-100% and right:-100%. Which is nothing but cover entire visible width.
.container {
display: block;
margin: 0 auto;
width: 50%;
background: grey;
height: 100vh;
}
.content {
position: relative;
width: 100%;
background: green;
}
.content::before {
content: "";
display: inline-block;
height: 100%;
background-color: green;
position: absolute;
top: 0;
right: -100%;
left: -100%;
z-index: -1;
}
<div class="container">
<p class="content">this is some text I want this text to be positioned here but the green background to span the whole width </p>
</div>
an idea using border-image
.container {
display: block;
margin: 0 auto;
width: 50%;
background: grey;
height: 100vh;
}
.content {
margin:0;
border-image: conic-gradient(green 0 0) fill 0//0 100vw;
}
<div class="container">
<p class="content">this is some text I want this text to be positioned here but the green background to span the whole width </p>
</div>

How do I center a div ontop of another div that has inline block

I'm trying to center a text div on top of box div that has inline block. I tried using position: absolute on the text div. But when the browser screen is shrunk or expanded, the positioning of the text div gets messed up. How to fix this?
.mainDiv {
margin: auto;
width: 100%;
padding: 10px;
left: 300px;
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
}
.text {
background-color: blue;
position: absolute;
top: 70%;
left: 45%;
}
<div class="mainDiv">
<div class="box"></div>
<div class="text">text</div>
</div>
I assume you are using inline-block to center the .box inside the .main-div. Technically, with your current html structure you can't center the .text element on the .box one, but you can center it on .main-div, which is essentially the same thing in your example.
I would start by adding position: relative to .main-div. An absolutely positioned element is positioned based on it's nearest ancestor that has a positioning context. The easiest way to set this is to add position: relative.
Then with your .text element you can adjust to:
.text {
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50% );
}
This works because top and left position the top and left element from the top and left of its parent. So the top of .text would start 50% of the way down .main-div, and likewise with left. This would leave your text too far down and to the left.
transform: translate values work differently - they are based on the size of the element itself. So -50% will move an element back half of its width or height. By setting it on both width and height we are moving the .text so that instead of its top and left edges being at 50%, it's center is at 50%.
.mainDiv {
position: relative; /* added to make .text align relative to this, not the document */
margin: auto;
width: 100%;
padding: 10px;
/* left: 300px; (I removed this for demo purposes, but if you need it you can add it back in) */
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
}
.text {
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50% ); /*pull the text left and up 50% of the text's size*/
}
<div class="mainDiv">
<div class="box"></div>
<div class="text">text</div>
</div>
The markup for text should be written first then the box. Then you may try using block instead of inline-block, then set the width of the text to 100 percent, display block and 'margin: 0 auto'. Also, maybe consider using the appropriate semantic tags as opposed to divs if you can. Also, I suspect the top and left rules to be causing the text to not align properly. You should no longer need position:absolute either.
If you want, you can make the blue div a child of the red div so that the blue div will always be relative to the red div. I also added position:relative to the red div, and used transform:translate to the blue div.
If I'm not mistaken, this is also responsive, so try shrinking your browser.
.mainDiv {
margin: auto;
width: 100%;
padding: 10px;
left: 300px;
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
position:relative;
}
.text {
background-color: blue;
position: absolute;
left: 50%;
transform:translate(-50%, -100%);
}
<div class="mainDiv">
<div class="box">
<div class="text">text</div>
</div>
</div>
.mainDiv {
text-align: center;
}
.box {
background-color: red;
width: 100px;
height: 100px;
display: inline-block;
margin-top: 19px;
}
.text {
background-color: blue;
position: absolute;
margin: -19px 0 0 36px;
}
<div class="mainDiv">
<div class="box">
<div class="text">text</div>
</div>
</div>

Prevent a pseudo element from changing the width/scroll width of a parent container?

I'm trying to put a green area, a pseudo element, to the right of of a blue element, the pseudo element's parent, such that the green element doesn't increase the width of the red scroll area, the container. My actual use-case is a bit more complex, but it relies on using a pseudo element so this below example sets up the problem well. I've included two blue areas and two green areas simply to show that I want the scroll area to scroll if the blue width is large enough. I just don't want the green area to be part of the calculation:
* {margin:0;padding:0}
div {
display: inline-block;
width: 200px;
height: 200px;
background-color: red;
overflow: auto;
}
span {
display: inline-block;
height: 50px;
position: relative;
background-color: blue;
vertical-align: top;
}
span:before {
content: '';
position: absolute;
left: 100%;
width: 500px;
top: 0;
bottom: 0;
background-color: green;
}
<div>
<span style="width:50px"></span>
<span style="width:250px"></span>
</div>
JS Fiddle
Ideally the green pseudo element would be pulled out of the layout completely and have no width. The problem is for the background-color to work it requires a width. I'm strongly suspecting I can't use background-color for this. If something like outline-right: 500px solid green; existed that would be a solution, but I can't find anything like that. I can't use box-shadow, border-right, or anything else since those all add to the width. Is there any mechanism in CSS that would allow the green area to not be included in the red's scroll width area?
Using an outer container with the inner one set to overflow: hidden; removes the absolutely positioned elements from being included in the width and scroll area calculation.
Using min-width: 100%; ensures that the inner container takes up at least the whole width of the outer container.
* { margin: 0; padding: 0; }
#first {
display: inline-block;
width: 200px;
height: 200px;
background-color: red;
overflow: auto;
}
#second {
display: inline-block;
overflow: hidden;
min-width: 100%;
}
span {
display: inline-block;
height: 50px;
position: relative;
background-color: blue;
vertical-align: top;
}
span:before {
content: '';
position: absolute;
left: 100%;
width: 500px;
top: 0;
bottom: 0;
background-color: green;
}
<div id="first">
<div id="second">
<span style="width:50px;"></span>
<span style="width:250px;"></span>
</div>
</div>
JS Fiddle

How to center and change the length of underline?

I have text that needs to be underlined only under the middle part of the word.
I have created the fiddle and I want the underline should be centered as shown in this image.
The CSS code which I have included in the fiddle are:
.footer p
{
width: 50%;
border-bottom: 1px solid #f51c40;
}
You can use an absolutely positioned pseudo element with left: 50%; transform: translate(-50%); to automatically center it horizontally relative to the content.
.footer p {
display: inline-block;
position: relative;
}
.footer p:after {
content: "";
height: 1px;
width: 50%;
background-color: red;
position: absolute;
bottom: -.5em;
left: 50%;
transform: translate(-50%);
}
<div class="footer">
<p>ADDITIONAL INFO</p>
</div>
you can use the ::after pseudo element. if you dont know what pseudo elemts are i recommend you learn about them here since its a very important part of CSS you will use often. the ::after pseudo element is able to add content after a certain element.
you can create a border after the p element for example:
.footer p::after {content:""; height: 1px; width: 50px; background-color: red;}
This can be done several ways and more info is needed from you...
Here is one way off the top of my head which is extremely straight forward
<div class="footer">
<p>Add<u>ition</u>al</p>
</div>
Another alternative would include using the .footer p :before and/or :after psuedo elements...
It should work like you need
footer p
{
width: 50%;
}
footer p:after {
content: '';
border-bottom: 2px #000 solid;
position: absolute;
top:40px;
left: 30px;
width:100px;
}
https://jsfiddle.net/74zgg81d/1/
The best way to do this to use the css pseudo elements ::after. Also you have to set display: inline-block and position: relative to the p element.
Please see the below snippet:
.footer p {
display: inline-block;
position: relative;
}
.footer p::after {
content: "";
width: 60px;
height: 3px;
background: black;
position: absolute;
left: 0;
right: 0;
margin: auto;
bottom: -3px;
}
<div class="footer">
<p>ADDITIONAL INFO</p>
</div>

Absolute position does not work on elements with % width

I have a div that has width set to 50%, and a border-radius of 50% in order to make it a circle. Inside there are 3 other divs that serve as buttons, and a fourth div, that serves the purpose of making it as tall as it is wide.
Now I want to position my buttons relative to the div .appContainer. Basically what I'm trying to achieve is that one button is always at the top center of the div, and the other two are at the bottom right and left corners.
Now something strange happens to my buttons - instead of positioning according to the parent element, when the parent div is smaller than the page, they are always positioned at the bottom of the screen.
Any ideas on how to achieve what I want to are appreciated.
If anything is unclear please let me know and I'll edit the main post.
body {
background-color: gray;
margin: 0;
padding: 0;
}
.appContainer {
width: 50%;
margin: 0 25%;
background-color: white;
border-radius: 50%;
}
.heightElement {
height: 0;
padding-bottom: 100%;
}
#button1, #button2, #button3 {
position: absolute;
background-color: red;
padding: 1em;
border-radius: 50%;
}
#button1 {
right: 50%;
top: 0%;
}
#button2 {
right: 25%;
top: 100%;
}
#button3 {
right: 75%;
top: 100%;
}
<div class="appContainer">
<div class="heightElement"></div>
<div id="button1">Button 1</div>
<div id="button2">Button 2</div>
<div id="button3">Button 3</div>
</div>
Your .appContainer might need a position: relative style rule.
.appContainer {
position: relative; // Try adding this line.
width: 50%;
margin: 0 25%;
background-color: white;
border-radius: 50%;
}
What this now means, is that anything within this item that is positioned absolutely, will be positioned relatively to its parent.
Here's a working demo for you: https://jsfiddle.net/usgp8ume/