Centering captions on FlexSlider using jQuery - javascript

FlexSlider 2 seems to position captions 10 pixels above the bottom of individual slides with this css from line 97 of flexslider.css:
.flexslider p {
position: absolute;
bottom: 10px;
}
To this I've added my own CSS:
.flexslider p {
font-family: 'Exo', san-serif;
font-size: 18pt;
text-align: center;
}
I noticed that other people asking about FlexSlider captions use a class called "flex-caption." This doesn't make sense to me, because the string "flex-caption" does not appear at all in my relatively recent versions of flexslider.css and jquery.flexslider-min.js. Nevertheless, I added the class to my HTML:
<div class="flexslider">
<ul class="slides">
<li>
<img src="images/slider/craft-the-future.jpg" />
<p class="flex-caption">Craft the future!</p>
</li>
<li>
<img src="images/slider/plugged-in.jpg" />
</li>
<li>
<img src="images/slider/athletics.jpg" />
</li>
<li>
<img src="images/slider/make-reality.jpg" />
</li>
</ul>
</div>
I decided that I need to add a left (or right) property to the absolutely positioned paragraph tag. Based mostly on Grinn's reply to this question, I decided to use JavaScript to find the pixel width of the paragraph tag, and then to subtract that width from the width of the slider box (720 pixels) before assigning the value to a left property.
I don't claim to know JavaScript or jQuery, but I've tried to do the best that I can with the tutorials and documentation available. I don't think I figured out how to load Grinn's plain JavaScript-heavy code as it is, so I decided to translate that method into a more jQuery-heavy format. I was finally successful in getting the browser to recognize the jQuery, since the alert does appear when I reload:
$(document).ready(function() {
var caption = $(".flexslider p");
alert(caption.length); // For debugging only
var indent = 720 - $(caption.innerWidth);
$(caption).css({
left: 'indent'
});
});
It doesn't seem to matter whether I use ".flexslider p" or ".flex-caption" to select the p tag.

You are assigning the value of left to be a string instead of your indent variable.
$(caption).css({
left: 'indent'
});
Should be:
$(caption).css({
left: indent
});

Related

Force hover state secondary element on click

quick question from a complete JS noobie.
On a site, I have an image of a product consisting of basically two parts, then I have a row of small .png thumbnails .colorthumbnail of those separate parts with transparent backgrounds. In the CSS I set it so that when hovering the thumbnails, it enables the .colorzoom class that overlays a big version of the same color option over the original product picture using position: absolute.
HTML:
<div class="coloroptions">
<div class="j210desertsand">
<div class="colorthumbnail">
<a href="javascript:void(0)" id="colorpicker">
<img src="img/products/colors/j210desertsand.png"></a>
<span class="colorzoom"><img src="img/products/colors/j210desertsand.png">
</span></div></div>
<div class="j210platinum">
<div class="colorthumbnail">
<a href="javascript:void(0)" id="colorpicker">
<img src="img/products/colors/j210platinum.png"></a>
<span class="colorzoom"><img src="img/products/colors/j210platinum.png">
</span></div></div>
</div>
The <div class="j210desertsand">classes are simply there so I can easily hide a single color option using CSS and the next colour will line up. The anchor points are there cause after some research I found I should actually make the thumbnails clickable and with a href="javascript:void(0)" they don't actually link anywhere or reload the page.
CSS: (Excuse the mess, I'm inexperienced)
.coloroptions {
width: 60%;
margin-left: 40%;
}
.colorthumbnail {
margin-left: -45%;
}
.colorthumbnail img {
float: left;
max-width: 16%;
padding-right: 5px;
position: relative;
}
.colorthumbnail .colorzoom {
position: absolute;
width: 253%;
margin-top: 6.9%;
display: none;
margin-left: -3.6%;
}
.colorthumbnail:hover .colorzoom {
display: block;
}
Now this appears to work fine, but because there are two different parts I want to give the user the ability to combine color options and obviously you can't hover over two images at once. After some more research I found that I need Javascript to force the :hover state on click. But I'm gonna be honest, I have no idea what I'm doing. This is what I have:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<!-- -----------------------JSQuery------------------------- -->
<script>
$("#colorpicker").click(function() {
$('.colorthumbnail:hover').toggleClass('colorthumbnail:hover .colorzoom');
});
</script>
<!------------------------ JSQuery End -------------------------->
However this does not appear to be working. Did I get the linked script in the <head> right? It did work alright with the 'Hello World' pop-up test. Did I get the classes in the script right? I'm a little stuck and help would be appreciated! Much love for the community.
Try adding your code like this:
$( document ).ready(function() {
$("#colorpicker").click(function() {
$('.colorthumbnail:hover')
.toggleClass('colorthumbnail:hover.colorzoom');
});
});
When trying to use jquery you need to make sure the page is loaded so it can perform dom manipulation.
source: https://api.jquery.com/ready/
Here is a jsFiddle demo: https://jsfiddle.net/Lv571n1w/
If you inspect element you can see it toggle the classes when clicked.

Z-index and stacking

I'm trying to figure out out to create a event to appear in front of my home without it opening a new page. It would, for lack of a better word, expand to fill the browser. I know I'll have to do some work with z-index and javascript. The month would hover and then the user would click to see the event.
Home and event
My HTML
<div class= "month sep_box">
<h1 class= "sep">SEP</h1>
<div class= "year">2016</div>
</div>
CSS
.sep_box{
background-image: url("images/design_disrupt.svg");
background-repeat: no-repeat;
background-size: cover;
background-clip: content-box;
background-position: center;
float: left;
width: 25%;
height: 25vh;
transition:.25s ease;
}
EDIT: Screen-shoted HTML now copied
<article>
<div><h1 id="design_disruptors">
DESIGN <br />DISRUPTORS</h1></div>
<div><p class="child_day">THURSDAY</p></div>
<div><p class="child_day_number">15</p></div>
<div><p class="child_event_about">JCM 2121<br />7:00pm</p></div>
<div><p class="child_rsvp">RSVP</p></div>
<div><p class="child_desc">Design Disruptors reveals<br />
a never-before-seen<br />
perspective on the design approaches of these<br />
companies and how they<br />
are overtaking billion dollar industries though design.</p>
</div>
</article>
https://jsfiddle.net/es60r7cv/
The comments aren't going to work at this point because of the character limit, so I'm going to try my best to give you some hints here. I am a little unsure as to how far along you are in your development to this point, and the intent of the design, but let's give it a shot.
Firstly, if I understand your design image correctly, you want almost the entire screen to look different except for the square that was clicked. This is going to be difficult, as you'll need to position a lot of elements in just such a way that you can have a transparency in exactly the right spot. Given your design, and how important pixel-perfection is going to be to making it work, and where you are in your development, I'm wondering if it would be ideal to simply fix the width of the whole design (no growing or shrinking with the screen).
I would also recommend you use jQuery for this project, as it will be easier for you.
To add an event listener to all your month boxes using jQuery, you would write it:
$(document).on('click', '.month', function (evt) {
// your event handling code here
}
I would give each month element an id for the month it represented, then create your overlays with a similar id. So, for example, the December month box would be <div class="month" id="december"><!--your_content--></div> and the overlay for the month could be <div class="overlay" id="decemberOverlay"><!--your_overlay_content--></div>. That way you could target it by getting the clicked month boxes id, and getting the overlay by doing that id + "Overlay".
You could fetch your overlay content on the fly using AJAX, but to reduce complexity for yourself you may just always load all overlays to the page and hide them with CSS, but also include the positioning code:
.overlay {
display: none;
z-index: 10;
position: absolute; /* this will position it to the document, or the first parent that is relatively or absolutely positioned */
top: 0;
left: 0
}
We are using absolute positioning because:
we want to be able to position the overlay directly over the original image, and not influence the flow of the rest of the document, and
z-index requires some non-static position value to be applied
Then, in your script, you would update it do be this:
$(document).on('click', '.month', function (evt) {
var clickedMonth = this.id;
var correspondingOverlay = $(clickedMonth+"Overlay");
correspondingOverlay.show();
}
Based on your fiddle and code, I think perhaps you are not very far along yet. Hopefully this gives you a bit of a head start on how to achieve your desired result.
Edit:
One last thing-- this is a cleaner way to style your markup:
<article>
<div>
<h1 id="design_disruptors">DESIGN <br />DISRUPTORS</h1>
</div>
<div>
<p class="child_day">THURSDAY</p>
</div>
<div>
<p class="child_day_number">15</p>
</div>
<div>
<p class="child_event_about">JCM 2121<br />7:00pm</p>
</div>
<div>
<p class="child_rsvp">RSVP</p>
</div>
<div>
<p class="child_desc">
Design Disruptors reveals<br />
a never-before-seen<br />
perspective on the design approaches of these<br />
companies and how they<br />
are overtaking billion dollar industries though design.
</p>
</div>
</article>
Clean HTML will be easier to read and easier to spot errors.

Is there an equivalent to the "alt" attribute for div elements?

Screenreaders will read whatever string is set to the "alt" attribute. The use of this attribute is specifically for image tags.
If I have a div like so:
<div id=myCoolDiv tabindex="0"> 2 <div>
Is there a way to have a screen reader pickup an attribute to read a string the same way an alt tag is used?
So for the div listed below, the screen reader will say ie: "shopping cart items 2"?
I tried using aria-label but the screenreader won't pick it up:
<div id=myCoolDiv tabindex="0" aria-label="shopping cart items"> 2 <div>
You can just put a title tag in the div which will do the same as an alt tag like so:
<div title="I AM HELLO WORLD">HELLO WORLD</div>
"I AM HELLO WORLD" will be printed once you move your cursor around it on a browser
There are two ways (which can be combined) to have screen reader to read alternative text:
Anything with ARIA role img can (MUST) have alt attribute. See WAI-ARIA img role.
<div role="img" alt="heart">
♥︎
</div>
UPDATE: In 2017 the WAI-ARIA document was changed and the following text does not apply anymore. See comments below.
However this should be used only in case the element really represent an image (e.g. the heart unicode character).
If an element contain actual text, that just need different reading, you should set ARIA role to text and add aria-label with whatever you want to be read by the screen reader. See WAI-ARIA text role.
<div role="text" aria-label="Rating: 60%">
Rating: ★★★☆☆︎
</div>
Do not mismatch it with aria-labeledby which should contain ID of an related element.
You can combine the previous two cases into one using two ARIA roles and adding both alt and aria-label:
<div role="img text" alt="heart" aria-label="heart">
♥︎
</div>
When more ARIA roles are defined, browser should use the first one that is supported and process the element with that role.
One last important thing is that you must set page type to HTML5 (which support ARIA by design).
<!DOCTYPE html>
Using HTML4 or XHTML requires special DTD to enable ARIA support.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+ARIA 1.0//EN"
"http://www.w3.org/WAI/ARIA/schemata/xhtml-aria-1.dtd">
Try role="listitem" or role="group" and aria-labelledby="shopping cart items". See Example 1. The 2 is text content which should be read by screen reader already with the attribute read as context to the content. Refer to this section.
UPDATE 2
Add aria-readonly=true role=textbox if you use an input. If there are doubts whether to use aria-label or aria-labelledby, read this article. In the documentation for JAWS and testing it myself supports the fact that aria-label is ignored. Furthermore, semantics are very important when accessibility is your concern. Using a div when you could use an input is not semantically sound and like I said before, JAWS would accept a form element more readily than a div. I assume that this "shopping cart" is a form or part of a form, and if you don't like it's borders, input {border: 0 none transparent} or use <output>* which would be A+ as far as semantics are concerned.
Sorry, #RadekPech reminded me; I forgot to add that using aria-labelledby needs visible text and that the text needs an id which is also listed as the value(s) of aria-labelledby. If you don't want text because of aesthetics, use color: transparent, line-height: 0, or color:<same as background>. That should satisfy visibility as far as the DOM is concerned* and still be invisible to the naked eye. Keep in mind these measures are because JAWS ignores aria-label.
*untested
EXAMPLE 3
<span id="shopping">Shopping</span>
<span id="cart">Cart</span>
<span id="items">Items</span>
<input id='cart' tabindex="0" aria-readonly=true readonly role="textbox" aria-labelledby="shopping cart items" value='2'>
UPDATE 1
For JAWS, you probably have to configure it a little:
Click the Utilities menu item.
Then Settings Center.
Speech and Sounds Schemes
Modiy Scheme...
HTML Tab
In this particular dialog box, you can add specific attributes and what is said when an element is tabbed to. JAWS will respond to form elements easier because they can trigger the focus event. You'll have an easier time doing Example 2 instead:
EXAMPLE 1
<div id=myCoolDiv tabindex="0" role="listitem" aria-labelledby="shopping cart items"> 2 <div>
EXAMPLE 2
<input id='semantic' tabindex="0" role="listitem" aria-labelledby="shopping cart items" value='2' readonly>
In case you use Bootstrap Framework there is a quick and easy solution. You should use sr-only or sr-only sr-only-focusable Bootstrap's CSS classes in a span element where your screen-reader-only text will be written.
Check the following example, a span element with class glyphicon glyphicon-shopping-cart is also used as cart icon.
<div id="myCoolDiv">
<h5>
<span class="glyphicon glyphicon-shopping-cart"></span> 2
<span class="sr-only sr-only-focusable" tabindex="0">shopping cart items</span>
</h5>
<div>
Screen Reader Output: "two shopping cart items"
provided by Fangs Screen Reader Emulator Addon for Firefox
You can find the above working example in this: Fiddle
As suggested by Oriol, in case you don't use Bootstrap Framework then simply add the following in your CSS file.
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
According to the text alternative computation algorithm of the W3C and the
Accessible Name and Description: Computation and API Mappings 1.1 you definitely should use aria-label.
That being said, it does not work with Jaws. Text alternative is only computed for elements having an ARIA role.
The remaining option is to use a link that will go to your cart page, using both title and aria-label to satisfy anyone:
2
You can also use a transparent 1 pixel option:
2 <img src="pixel.png" height="1" width="1" alt="shopping cart items" />
No, there is no equivalent to an alt attribute for <div> elements.
For what you are trying to do, an ARIA-based solution is overkill. Not only are you bumping into screen reader compatibility problems, you are applying ARIA attributes where they are not needed (and arguably do not belong if on something like a <div>).
Instead, consider using an off-screen technique (such as this one from The Paciello Group or this one from WebAIM). Content hidden using this technique will still be read by screen readers but will be visually hidden.
From reading your question, I think this is what you are after.
I made a pen demonstrating this technique. It may be easier to test in the full-page version.
Edit: Added HTML and CSS from the example, but please note that both the specs and browser / assistive technology support change over time, so if you are reading this in a year you should continue to use the links above to verify this CSS is still the current best practice.
HTML
<div tabindex="0">
<span class="offscreen">Items in shopping cart: </span>2
</div>
CSS
.offscreen {
position: absolute;
clip: rect(1px 1px 1px 1px);
/* for Internet Explorer */
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;
}
Accessibility (Screen readers) can be achieved through role and aria-label tags on div. This can be very useful while using svg.
<div role="img" aria-label="I can speak the text">
<svg>...</svg>
</div>
Try:
HTML
<div id=myCoolDiv tabindex="0"><span class="aria-hidden">shopping cart items</span>2<div>
CSS
.aria-hidden {
position: absolute;
left: -100000px;
}
This will announce the text inside the span. And the Parent div will not lose visual focus. Aria-hidden class will hide the span from the visible screen area but will read it as its inside the div that has focus.
You can create a class such as screen-reader-text with the following css:
.screen-reader-text {
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
width: 1px;
overflow: hidden;
position: absolute !important;
}
Then, in your code, you can just add a <span> with the screenreader text as so:
<div>
I am a div!
<span class="screen-reader-text">This is my screen reader text</span>
</div>
See an example over here: https://jsfiddle.net/zj1zuk9y/
(Source: http://www.coolfields.co.uk/2016/05/text-for-screen-readers-only-updated/)
Use an image inside the div that has the label as its alt attribute. That way, those without screen readers just see the number and an image, whereas those with readers will hear the whole sentence:
<div>
<img src="http://tny.im/57j" alt="Shopping cart items" />
2
</div>
Seen as:
2
Read as: "Shopping cart items: 2"
The alt attribute exists for images because there is no way to "read aloud" the content of the image, so the provided text is used instead. But for the div, it already contains text and images. Therefore, if you want it to be read by a screen-reader, you need to include the text and alt text in the content of the div.

CSS Style only text within a paragraph tag

I have a page of text and it is formatted similar to this
<div class="container">
<p style="text-align: center;">
<span style="text-decoration: underline;">
<strong>
<img src="//cdn.shopify.com/s/files/1/0652/9219/files/Horizontal.jpg?13817493546805475501" alt="">
</strong>
</span>
</p>
<p style="text-align: center;">
<span style="text-decoration: underline;">
<strong>The Hosting</strong>
</span>
</p>
<p>
The in-laws are arriving, friends are in town, and everyone is heading to your abode for a night filled with holiday cheer. As stress levels tend to rise during these events, expenses do as well. Here are a few tips to nail your hostess game, without breaking the bank and <em>still</em> shopping consciously.
</p>
</div>
I am looking to keep the images which fit the entire content width of the class container the same but only change the text within the paragraph tags to either be a smaller width (so it looks indented on both sides) or have margins but not affect the images at all. I cannot change how the code is outputted so the images will always be wrapped in paragraph tags.
This code is a small sample on the page of content and there are several images and text throughout.
So basically I am looking for a way in css to style only the actual text within the paragraph tags and leave the images unchanged. Any help would be great.
Here is a fiddle example: https://jsfiddle.net/jpautt8v/
If your html is static or if you know which child you want to modify then you could simply use the nth child css selector to apply css like below 3rd in your sample code case. You could play around margins and see what works best for your solution.
p:nth-child(3)
{
margin: 0 50px;
}
Without changing any of the existing markup, you can accomplish what you want using negative margin.
Something like this will work:
img {
width: 120%; max-width: 120%;
margin: 0 -10%;
}
.content > div, .content > p {
margin: 0 10%;
}
You can see it working in this fiddle: https://jsfiddle.net/igor_9000/jpautt8v/1/

Overlapping elements using Sticky-kit (jQuery plugin) because navbar automatically fills window

I want to achieve a navbar that is first stickied to the bottom of the page. No matter what height the window is, it will stick on the bottom - then I want it to be stickied on top upon scrolling.
I am able to achieve that through a jQuery library, Sticky-Kit http://leafo.net/sticky-kit/. However, all my other elements are overlapped by the navbar. I have changed the z-index of my other elements, that works but now the navbar is overlapped. Same problem, different element. Plus, it doesn't look nice as my content looks like as it goes on the navbar rather than underneath it.
The code on jsfiddle will help you get a picture of what I'm trying to achieve:
http://jsfiddle.net/u6aNX/
In the jsfiddle link above, it does not fully replicate my project but it does replicate the problem. The navbar height increase allowing other elements to be overlapped. Although on my project it does show that it increase but when I check on Chrome Dev Tools, I can see that the height of it is the same as the window.
Extra info:
I am using Bootstrap. .navbar is from Bootstrap
Code:
HTML:
<div class="navbar navbar-bottom" id="sticker">
<div class="container">
<a class="brand" href="https://twitter.com/duaneadam" id="duane-brand">#duaneadam</a>
<ul class="over-nav nav">
<li>Home</li>
<li>About</li>
</ul>
</div> <!-- /container -->
</div> <!-- /navbar /navbar-bottom -->
<div>
<h2>Hello World!</h2>
<p>
Lorem ipsums here to achieve scrolling. Check jsfiddle link
</p>
</div>
CSS: (Custom, overriding Bootstrap)
.navbar-bottom {
position: absolute;
bottom: 0;
right: 0;
left: 0;
margin: 0px;
}
.navbar {
background-color: #ccff22;
}
JavaScript/jQuery:
/*
Sticky-kit v1.0.1 | WTFPL | Leaf Corcoran 2013 | http://leafo.net
*/
(function(){var g,t;g=this.jQuery;t=g(window);g.fn.stick_in_parent=function(d){var u,k,e,r,B,h,C;null==d&&(d={});r=d.sticky_class;u=d.inner_scrolling;e=d.parent;k=d.offset_top;null==k&&(k=0);null==e&&(e=void 0);null==u&&(u=!0);null==r&&(r="is_stuck");B=function(a,d,h,v,y,l){var p,s,m,w,b,f,z,A,q,x;f=a.parent();null!=e&&(f=f.closest(e));if(!f.length)throw"failed to find stick parent";z=function(){var c,b;c=parseInt(f.css("border-top-width"),10);b=parseInt(f.css("padding-top"),10);d=parseInt(f.css("padding-bottom"),
10);h=f.offset().top+c+b;v=f.height();c=a.is(".is_stuck")?q:a;y=c.offset().top-parseInt(c.css("margin-top"),10)-k;return l=c.outerHeight(!0)};z();if(l!==v)return m=a.css("float"),q=g("<div />").css({width:a.outerWidth(!0),height:l,display:a.css("display"),"vertical-align":a.css("vertical-align"),float:m}),p=s=!1,w=void 0,b=k,A=!1,x=function(){var c,g,n,e;n=t.scrollTop();null!=w&&(g=n-w);w=n;s?(e=n+l+b>v+h,p&&!e&&(p=!1,a.css({position:"fixed",bottom:"",top:b}).trigger("sticky_kit:unbottom")),n<y&&
(s=!1,b=k,"left"!==m&&"right"!==m||a.insertAfter(q),q.detach(),c={position:""},A&&(c.width=""),a.css(c).removeClass(r).trigger("sticky_kit:unstick")),u&&(c=t.height(),l>c&&!p&&(b-=g,b=Math.max(c-l,b),b=Math.min(k,b),a.css({top:b+"px"})))):n>y&&(s=!0,c={position:"fixed",top:b},"none"===m&&"block"===a.css("display")&&(c.width=a.width()+"px",A=!0),a.css(c).addClass(r).after(q),"left"!==m&&"right"!==m||q.append(a),a.trigger("sticky_kit:stick"));if(s&&(null==e&&(e=n+l+b>v+h),!p&&e))return p=!0,"static"===
f.css("position")&&f.css({position:"relative"}),a.css({position:"absolute",bottom:d,top:""}).trigger("sticky_kit:bottom")},t.on("scroll",x),setTimeout(x,0),g(document.body).on("sticky_kit:recalc",function(){z();return x()})};h=0;for(C=this.length;h<C;h++)d=this[h],B(g(d));return this}}).call(this);
$(document).ready(function() {
$("#sticker").stick_in_parent();
});
Your problem is position:absolute, and bottom:0, after you navigation stuck to the top (sticky kit adds style="top:0") and it gets stretched to the bottom of the page.
just add this function:
$("#sticker").stick_in_parent()
.on("sticky_kit:stick", function(e) {
$(".navbar").removeClass("navbar-bottom");
})
which does something when element "is sticky"
opposite to that one is:
.on("sticky_kit:unstick", function(e) {
//do something when "not sticky"
});
http://jsfiddle.net/u6aNX/2/
If you want your navbar to goes back to "onload" position when you scroll up
.on("sticky_kit:unstick", function(e) {
var top_bar = document.getElementById ("sticker");
top_bar.style.top = "";
$(".navbar").addClass("navbar-bottom");
});
http://jsfiddle.net/u6aNX/3/

Categories

Resources